搜索
查看: 1737|回复: 27
打印 上一主题 下一主题

逻辑大挑战链表4

[复制链接]
跳转到指定楼层
楼主
发表于 2014-6-22 23:03:12 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 超神级 于 2014-6-22 23:11 编辑

关于3动态内存分配这篇明天补上.可以明天再来.
关于链表篇的话就使用<问题出现解决问题的思路来讲>
数组和链表的区别:
  数组:    优点:使用方便 ,查询效率 比链表高,内存为一连续的区域
    缺点:大小固定,不适合动态存储,不方便动态添加
    链表:
     优点:可动态添加删除   大小可变   
     缺点:只能通过顺次指针访问,查询效率低
  在访问方式上   
        数组可以随机访问其中的元素   
        链表则必须是顺序访问,不能随机访问   
     
空间的使用上   
        链表可以随意扩大   
        数组则不能   
好了上面都是老套话现在真正开始:
         在数据的存储上数组和链表有显著的区别(地址的连续和不连续)我们怎么解决这个问题使得链表可以近似于数组
因为我们之前学过了结构体我们可以定义一个这样的结构体使得当前的链表节点可以找到下一个节点
可以定义一个这样的一个结构体
struct ahc

        int shuju;//数据
        int *xia;//存储下个节点的地址


┌─  ───────┬───┐
│data数据 │next 下个│

└─────────┴───┘
看到上面的那个图像了把先来几个链表的专业术语记不记无所谓的
图像里面的head是头节点..然后依次是是首节点...尾节点...
有了上面那个结构体我们就可以试着写链表了‘
我们先这样写
#include<stdio.h>
#include<malloc.h>//动态内存分配要的头文件
struct ahc
{
    int shuju;
  struct ahc*xia;//下一个节点的地址..
};
int main()
{

    ahc to;
    return 0;
}
这样写了以后我们还要写一部分算法,分配几块内存然后把他们串起来...假设我们需要5个节点
写好后应该是这个样子
#include<stdio.h>
#include<malloc.h>//动态内存分配要的头文件
struct ahc
{
    int shuju;
    struct ahc*xia;//下一个节点的地址
};
struct ahc *hanshu(void)
{
     int b,c;
struct ahc*to=(struct ahc*)malloc(sizeof(struct ahc));//VC6上不强制转换编译通不过。。。=_=!.
struct ahc*to2=to;
    for(b=1;b<=5;b++)
    {
        printf("请输入你要增加的shuju\n");
        scanf("%d",&c);
       struct ahc*xia2=(struct ahc*)malloc(sizeof(struct ahc));
       xia2->shuju=c;
        to2->xia=xia2;///to=to2->xia;两种方式
    }
   
      return to;
}
int main()
{

    ahc *to;
    to=hanshu();
    return 0;
}
简单吧核心代码就十几句.
关键点:
为什么要建立to2这个指针呢?????
我们把to的指向的那块储存空间赋值给了to2,to2也就是相当于to。
因为如果我们不定义to2节点的话to节点一直在变化我们就找不到指针的首地址了。
     xia2->shuju=c;
        to2->xia=xia2;///to=to2->xia;两种方式
为什么找不到呢!观察上面两段语句.
关键点:
to2->xia=xia2;
ps:观察上面语句。不要搞混了xia和xia2的关系.
...然后要考虑到多方面因素我们还需要加些代码。


例如我们不知道链表什么时候会结束(在我们不知道几个节点的情况下)
#include<stdio.h>
#include<malloc.h>//动态内存分配要的头文件
struct ahc
{
    int shuju;
    struct ahc*xia;//下一个节点的地址
};
struct ahc *hanshu(void)
{
     int b,c;
struct ahc*to=(struct ahc*)malloc(sizeof(struct ahc));//VC6上不强制转换编译通不过。。。=_=!.
struct ahc*to2=to;
    for(b=1;b<=5;b++)
    {
        printf("请输入你要增加的shuju\n");
        scanf("%d",&c);
       struct ahc*xia2=(struct ahc*)malloc(sizeof(struct ahc));
       xia2->shuju=c;
        to2->xia=xia2;///to=to2->xia;两种方式
        xia2->xia=NULL;
    }
   
      return to;
}
int main()
{

    ahc *1to;
    to=hanshu();
    return 0;
}
//比上面的代码多了个xia2->xia=NULL;这是为了什么.加个结束符,便于操作.
好了现在差不多了..明天再写遍历和释放内存,


1048521.jpg (13.83 KB, 下载次数: 0)

1048521.jpg

评分

参与人数 1啊哈币 +10 收起 理由
李掌柜 + 10 不错不错,很给力的教程

查看全部评分

沙发
 楼主| 发表于 2014-6-22 23:11:01 | 只看该作者
写的有些匆忙如有错误请指出...以免误导后来者..
板凳
发表于 2014-6-25 20:31:34 | 只看该作者
没看先赞,话说这是精华啊~
地板
 楼主| 发表于 2014-6-25 21:37:12 | 只看该作者
cad20020601 发表于 2014-6-25 20:31
没看先赞,话说这是精华啊~

怎么样?..
5#
发表于 2014-6-26 10:35:28 | 只看该作者
话说
  1. struct ahc

  2.         int shuju;//数据
  3.         int *xia;//存储下个节点的地址

复制代码

int *是怎么回事?

然后你还在写malloc.h ?

我的建议是你先把vc6丢掉,然后去把老外随便哪本英文教材看透了,然后再写教程教别人吧
6#
发表于 2014-6-26 16:33:41 | 只看该作者
[mw_shl_code=c,true]#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

typedef struct Node
{
        int data;               //数据域
    struct Node *pNext;     //指针域
}NODE,*PNODE;               //NODE等价于struct Node
                            //PNODE等价于struct Node *

//函数声明
PNODE create_list(void);
void traverse_list(PNODE);

int main()
{
        PNODE pHead;
   
    pHead = create_list();
    traverse_list(pHead);
   
        system("pause");
        return 0;
}

PNODE create_list(void)    //创建链表
{
        int len;               //用来存放有效节点的个数
    int i;
    int val;               //用来临时存放用户输入的节点的值
    //分配了一个不存放有效数据的头节点
    PNODE pHead;
    pHead = (PNODE)malloc(sizeof(NODE));
    if(pHead == NULL)
    {
                printf("分配失败,程序终止!\n");
        exit(-1);
    }
   
    PNODE pTail = pHead;
    pTail->pNext = NULL;
   
    printf("请输入您需要生成的链表节点的个数:len =");
    scanf("%d",&len);
    for(i=0; i<len; i++)
    {
                printf("请输入第%d个节点的值:",i+1);
        scanf("%d",&val);
        //动态创建新的节点
        PNODE pNew = (PNODE)malloc(sizeof(NODE));
        if(pNew == NULL)
        {
                        printf("分配失败,程序终止!\n");
                        exit(-1);
        }
        pNew->data = val;    //将输入的值赋给data成员
        pTail->pNext = pNew; //将新的节点连接到上一个节点
        pNew->pNext = NULL;  //空值赋值给新的节点的指针成员
        pTail = pNew;        //最后将pNew的地址赋值给pTail,让pTail指向最新的节点
    }
    return pHead;   //返回值为pHead头指针(头结点的首地址)
}

void traverse_list(PNODE pHead)
{
        PNODE P;
    P = pHead->pNext;
   
    while(P != NULL)
    {
                printf("%d  ",P->data);
        P = P->pNext;
    }
    printf("\n");
    return;
}[/mw_shl_code]
7#
 楼主| 发表于 2014-6-26 20:16:58 | 只看该作者
本帖最后由 超神级 于 2014-7-15 21:40 编辑
rosynirvana 发表于 2014-6-26 10:35
话说

int *是怎么回事?


int *哪是个错误!后面审文看到这个错误!但是我并未去修正!
理由如下:
1.int*的确可以指向一块内存区域..(这里是个欺骗心理让大家自以为是这样)!如果我写  struct ahc*xia;很多人不明白这定义的是什么东东).
很少人真正明白链表结构体里定义一个对象的真正含义!定义一个个指针对象的用途是什么!
就是在链表的节点无限延伸的时, "可以访问到当前深度的成员变量"这句话看这好理解不过很多人会忽略其中
的转化!
2.链表只是一个很(狭义)的定义!写教程之初我本来思考一种比链表还要简单点的数据结构..最后无疾而终...
想来想去都没有链表来的实在!
二.然后你还在写malloc.h ?
malloc.h...我一直都是这样写吖....上次你写的哪篇动态内存分配我就看了一点...
三..我电脑上有VS的一般节约时间我都是使用VC6。。大神是否可以推荐款编译器..
还有就是我英文很差看英文书籍很浪费时间学不会!看翻译的话感觉很少书翻译的可以让人看明白..
我比较喜欢看国内的教材,因为这是人家把外国的知识学到然后再使用中国人的思维教!
8#
 楼主| 发表于 2014-6-26 20:19:23 | 只看该作者
小乖代码 发表于 2014-6-26 16:33
[mw_shl_code=c,true]#include
#include
#include

这么标准的链表,虽然学习是种模仿的过程但是这个也太标准了把!
9#
发表于 2014-6-27 00:27:08 | 只看该作者
超神级 发表于 2014-6-26 20:16

int *哪是个错误!后面审文看到这个错误!但是我并未去修正!
理由如下:

我上次也说过了,如果要分布讲解强调链表单元格在数据结构层面的本质,把所有单元格都放在数组里,然后用一个变量记录数组下标比较好
在代码里写似是而非的东西是不好的,何况你的排版做得并不好

malloc.h根本不是任何一个C语言标准库中所含有的头文件
malloc函数族的定义在stdlib.h中,写malloc.h的代码看上去就像25年前的东西一样

编译器有mingw可以用,不过看上去你对微软有点中毒所以我建议去弄个linux的环境吧
有人说摆脱微软是认真学习的第一步,略偏颇但是在国内还是很有道理的

国内真的有C语言教材能看吗,我是没见到
国内很多人认为自己懂C,但是大多数都不怎么通
而且很多人也是在微软环境下学习的,c和cpp都不分,微软扩展和标准c也不分
真正学得扎实的少壮一派程序员还没空写书

C的问题不在于思维模式,而是涉及到的内容太多
对于一个纯兴趣没目的的人而言,学C本来就走错了路了
10#
 楼主| 发表于 2014-6-27 21:15:16 | 只看该作者
rosynirvana 发表于 2014-6-27 00:27
我上次也说过了,如果要分布讲解强调链表单元格在数据结构层面的本质,把所有单元格都放在数组里,然后用 ...

嗯、

好像听你以前说过malloc这个问题。想起了。

大神你使用的是mingw?!你用是什么编译器?..我对微软也不是很有好感...听人说linux使用很麻烦!我怕麻烦...

还可以吧!....不过我也看国外的一些翻译的比较好的名作!...还好吧...!

C涉及问题确实很多!很复杂..很多语言都是如此!
.....还好吧!我现在主要精力没放在C上..!

11#
发表于 2014-6-28 11:50:31 | 只看该作者
超神级 发表于 2014-6-27 21:15
嗯、

好像听你以前说过malloc这个问题。想起了。

主流的编译器我都在用,unix的gcc clang windows下面的mingw
我能分清楚哪些是标准哪些是编译器扩展,从你的代码上来看,你分不出,所以建议你别用都是扩展的vc6

linux麻烦不麻烦在于你要的是linux还是一个像windows的linux,后者当然麻烦

国内的那些书真的是不可以,说不上“还好”

很多语言都是如此⋯⋯你说的是php里面要嵌入sql那个级别的?
C好多东西涉及到操作系统,复杂度不是别的很多语言能比的
而且C也不是以实现为标准的,条文标准里又有很多未定义的行为
外加标准库太小干不了事,链接又是涉及到操作系统级别的概念⋯⋯

很多语言只是东西多,复杂就谈不上了
12#
发表于 2014-6-28 20:41:16 | 只看该作者
超神级 发表于 2014-6-26 20:19
这么标准的链表,虽然学习是种模仿的过程但是这个也太标准了把!

虽然我是在模仿  毕竟我学习C语言已经两个月咯!!但是我已经能完全理解链表。这个代码毕竟是我一步步打出来的,我自我觉的不错,适合初学的人
13#
 楼主| 发表于 2014-6-28 20:52:15 | 只看该作者
小乖代码 发表于 2014-6-28 20:41
虽然我是在模仿  毕竟我学习C语言已经两个月咯!!但是我已经能完全理解链表。这个代码毕竟是我一步步打 ...

加油!。。。
14#
发表于 2014-6-28 20:55:21 | 只看该作者

现在已经在看数据结构  和王爽的汇编   说实话汇编让我对语言有种其他的看法
15#
 楼主| 发表于 2014-6-28 21:08:31 | 只看该作者
rosynirvana 发表于 2014-6-28 11:50
主流的编译器我都在用,unix的gcc clang windows下面的mingw
我能分清楚哪些是标准哪些是编译器扩展,从 ...

嗯.是这样的我并不熟悉标准和编译器扩展..弱弱问下使用mingw最大的原因是什么?
嗯.懂了!
...好吧!
一些乱七八糟的东西吧!

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

广播台
特别关注
快速回复 返回顶部 返回列表