| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 582 人关注过本帖
标题:刚开始接触链表,看了许多创建方面的,但是还是有点疑惑!!!!!!!谢谢 ...
只看楼主 加入收藏
笔墨痕干
Rank: 1
等 级:新手上路
威 望:1
帖 子:56
专家分:0
注 册:2014-3-24
结帖率:84.21%
收藏
已结贴  问题点数:20 回复次数:10 
刚开始接触链表,看了许多创建方面的,但是还是有点疑惑!!!!!!!谢谢了
#include<stdio.h>
#include<stdlib.h>
typedef struct Lnode
{
    int data;
    struct Lnode *next;
}ListNode;
typedef ListNode *LinkList;
LinkList Create()
{
    LinkList head,p,q;
    int x;
    p=(ListNode *)malloc(sizeof(struct Lnode));
    p=head;
    printf("请输入链表中的第一个输入数据\n");
    scanf("%d",&x);
    printf("请继续往链表中输入数据,以(-1)为停止输入标志\n");
    while(x!=-1)
    {
        q=(ListNode *)malloc(sizeof(struct Lnode));
        q->data=x;
           p=q;
        p=p->next;
        scanf("%d",&x);
    }
    p->next=NULL;
    return p;
}
void Print(LinkList head)
{
    LinkList p;
    p=(ListNode *)malloc(sizeof(struct Lnode));
    p=head;
    printf("输出链表中的数据\n\n");
    while(p!=NULL)
    {
        printf("%d",p->data);
        p=p->next;
    }

}
void main()
{
    LinkList *head;
    head=(ListNode *)malloc(sizeof(struct Lnode));
    head=Create();
    Print(head);

}
帮忙看下吧!!为什么输不出来啊!!最大的原因应该就是在循环输入的地方
搜索更多相关主题的帖子: Create include 
2014-04-09 20:08
杰子021
Rank: 1
等 级:新手上路
帖 子:9
专家分:0
注 册:2014-4-8
收藏
得分:0 
真高深
2014-04-09 20:54
ying8501
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:6
帖 子:1092
专家分:1446
注 册:2008-11-24
收藏
得分:5 
你自己对照一下吧。
//带头结点的链表
#include<stdio.h>
#include<stdlib.h>
typedef struct Lnode
{
    int data;
    struct Lnode *next;
}ListNode;
typedef ListNode *LinkList;

LinkList Create()
{
    LinkList head,p,q;
    int x;
    p=(ListNode *)malloc(sizeof(struct Lnode));
    head=p;
    printf("请输入链表中的第一个输入数据\n");
    scanf("%d",&x);
    printf("请继续往链表中输入数据,以(-1)为停止输入标志\n");
    while(x!=-1)
    {
        q=(ListNode *)malloc(sizeof(struct Lnode));
        q->data=x;
        p->next=q;
        p=q;
        scanf("%d",&x);
    }
    p->next=NULL;
    return head;
}

void Print(LinkList head)
{
    LinkList p;

    p=head->next;
    printf("输出链表中的数据\n\n");
    while(p!=NULL)
    {
        printf("%4d",p->data);
        p=p->next;
    }
    printf("\n");
}
void main()
{
    LinkList head;

    head=Create();
    Print(head);

}
2014-04-09 21:47
杨攀好
Rank: 2
等 级:论坛游民
威 望:1
帖 子:41
专家分:32
注 册:2014-3-24
收藏
得分:0 
深奥啊   表示我这种菜鸟看不懂
2014-04-09 22:06
笔墨痕干
Rank: 1
等 级:新手上路
威 望:1
帖 子:56
专家分:0
注 册:2014-3-24
收藏
得分:0 
回复 3楼 ying8501
首先谢谢你!!
但是还想问下 p->next=q;p=q;是什么意思啊?
p->next=q,是不是说把q的地址告诉p,
p=q也是把q的地址告诉p吧?我们老师说过指针就是地址啊!!!!p并没有往下移动啊!!!
求解惑!!!!
2014-04-10 09:52
Andrew_Lee
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:3
帖 子:185
专家分:626
注 册:2014-3-21
收藏
得分:0 
简单来说,这两行要完成下面这个操作:
图片附件: 游客没有浏览图片的权限,请 登录注册



[ 本帖最后由 Andrew_Lee 于 2014-4-10 10:20 编辑 ]
2014-04-10 10:19
笔墨痕干
Rank: 1
等 级:新手上路
威 望:1
帖 子:56
专家分:0
注 册:2014-3-24
收藏
得分:0 
回复 6楼 Andrew_Lee
能不能别说的这么简单啊!!我是看不懂啊 !!!给点文字说明好吗??谢谢了!!!!
2014-04-10 17:23
Andrew_Lee
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:3
帖 子:185
专家分:626
注 册:2014-3-21
收藏
得分:5 
q指向的是你要添加到链表中的数据,p是链表中你要添加的位置。就是q指向的数据要添加到p指向数据的后面。
p->next=q 就是p的后向指针指向q 图的前一个部分将2添加到1的后面,a->b->c->1->2,这个时候p指向1,q指向2
p = q;p就指向2了,说明下一个数据要添加在2的后面。记住数据要添加到p的后面,所以你每次添加一个数据,p就应该指向后面一个。

我檫,感觉还是图形比较清楚,,都被我说乱了。。你还是到网上搜个关于链表的视频看看比较靠谱
2014-04-10 18:00
笔墨痕干
Rank: 1
等 级:新手上路
威 望:1
帖 子:56
专家分:0
注 册:2014-3-24
收藏
得分:0 
回复 8楼 Andrew_Lee
无论如何还是谢谢你了!!!谢谢!!
2014-04-10 18:57
神机军师
Rank: 7Rank: 7Rank: 7
来 自:游鱼潜水
等 级:黑侠
威 望:2
帖 子:202
专家分:542
注 册:2013-12-21
收藏
得分:10 
楼上正解,关于指针传递确实是这样的。
你的输出函数:
程序代码:
void Print(LinkList head)
{  // 输出函数式传递一个构造体指针,无返回值,通过构造体的next指针传递来依次输出数据
    LinkList p; 
    p=(ListNode *)malloc(sizeof(struct Lnode));// 这里不用创建,这个函数主要是通过指针操作的
                                               // 这里多余了,下面的p = head会使这里的分配内存
                                               // 丢失,无法回收。
    p=head;
    printf("输出链表中的数据\n\n");
    while(p!=NULL)
    { // 之前可以稍微加个判定 if (p = NULL) {printf("NULL\n");return ;}
      // 主要是稍微加强了一下错误参数输入的判定,实际上只是有一点点作用
        printf("%d",p->data);
        p=p->next;
    }
}


输出函数应该是没神马错误啦,如果那接着看看建立函数:
程序代码:
LinkList Create()
{ // 链表创建函数,无形式参数,返回构造体指针(构造体就是结构体。。)
    LinkList head,p,q;
    int x;
    p=(ListNode *)malloc(sizeof(struct Lnode));// 看程序的建立函数,链表头指针是不存储信息的,
                                               // 但是输出函数式从head头指针输出的,所以后面改一下


    p=head;  // 这个有问题 0.0 应该是head = p; head刚刚创建,还是野指针,这样乱赋值会出问题
             // 所以建议。。。每个指针刚创建,不管初始化与否,都用 
             // LinkList head = NULL;
             // LinkList p    = NULL;
             // LinkList q    = NULL;
             // 后面再进行赋值神马的,虽然麻烦了点,但是能减少出错
             // 这里,如果是p = head,就是把head的值(里面存储的是个LinkList类型的指针,也就是个地址)
             // 赋给p,head没有进行初始化,里面数值随机,这里p的值也就随机了,然后再进行*p.xxx
             // 或者p->xxx就会出问题
    printf("请输入链表中的第一个输入数据\n");
    scanf("%d",&x);
    printf("请继续往链表中输入数据,以(-1)为停止输入标志\n");
    while(x!=-1)
    {  // 这个循环是Creat函数算法的核心,建议拿个纸和笔画流程,包括刚开始链表还没有结点的时候
       // 前面有结点后面也有结点的时候,以及到链表尾结点的时候,这都具有代表性,希望楼主能搞明白
       // 说来说去,链表基本上玩的就是这些个东西 ~~~~!!!!
        q=(ListNode *)malloc(sizeof(struct Lnode));
        // 这里,又重新给q分配内存空间了,也就是说while循环前面的malloc语句白白浪费了一部分内存
        // 所以,我想着,换一下语句顺序,因为最后我想要返回head值(就是头指针)所以head要接受第
        // 一个数值(根据输出函数来说,头指针应该存放数据的,而且写这里这个算法的时候也请想一下
        // 如果,要创立链表,只是想要一个空链表该怎么完善这个算法(就是head = NULL))
        // 所以,这里我增加了选择结构的语句,来区别对待p是否是头指针的情况。
        q->data=x; // 赋值,没啥说的。
           p=q;    // 看到这里,感觉有点乱,q是while()前分配的内存空间(但是实际上经过p = head后
                   // 那个内存已经丢失了,因为再也找个到他的地址了,已经遗失了,所以后面我综合了一下
                   // 重新写了这一部分的循环)
        p=p->next; // 处理链表,这个很常见,有的意义并不一样,例如上面p->next = q->next,p->next = q
        scanf("%d",&x);
    }
    p->next=NULL; // 尾结点的处理。
    return p;
// 重新想一下程序的顺序,要尽量正确,在正确的基础上尽量易读(其实要求很多,先满足正确和规范格式吧)
// 我从你的语句:p=(ListNode *)malloc(sizeof(struct Lnode)); 后面继续写了,最后是返回head
// head = NULL;
// printf("请输入链表中的第一个输入数据\n");
// scanf("%d",&x);
// printf("请继续往链表中输入数据,以(-1)为停止输入标志\n");
// while(x! = -1)  
// {
// //进行到这里了,就说明,x != -1也就是一定会有个数据要输入,也就是说要有个结点加入链表
//     if (NULL == head) // 一个小习惯,有时候能避免出错
//     { // 如果head还是空的,也就是链表还没有结点的加入,那么先把头结点加入,此时已经创建了p了
//          head = p;
//          q = head; // 增加这一句是为了后面的连贯性,如果没有的话,在进行一次while循环,就
//                    // 进行else语句了,这时候链表会断掉,因为head和q还没有建立关系(其实这里
//                    // 可以写成q = p;然后和else里面的q = p一起整合到if循环语句的外面)
//      }
//     else  // head不是空,说明前面已经有了结点,这个是续接新的结点 
//     {
//          q->next = p; // 写的时候,新手这里可能会抓瞎,所以要想一下,如果这是续接的新结点
//                       // 而不是头结点,那么一定已经malloc新的空间了,而且空间地址赋值给了p
//                       // 这里只把p接上就行了。
//          q = p;   // 把q的指针指向后面的结点(这个就是q = q->next)
//      }
//      p->data = x; // 结点接上以后接着就要赋值,这时候p还是指向刚刚接上的那个结点
//      p = (ListNode *)malloc(sizeof(struct Lnode)); // 建立新的结点分配内存空间
// } // 循环结束
// free(p); // 在这个循环里面,不管何种情况,都会多分配一个内存空间,所以要释放掉
// // 处理尾巴
// if (NULL == head) // 上面介绍了这种情况,这时候访问head->next会出错
// {
//     return(NULL); // 这时候直接返回空指针,其实返回head也行的。
// }
// else // 不是空链表
// {
//     q->next = NULL;
//     return(head);
// }
// 改动到这里就结束啦,不看不知道,发现我还是很啰嗦的,另外改动并没有经过编译器和实际验证,
// 有些字符可能是中文字符,直接复制粘贴会不给通过。还有,上面这个改动是针对循环外就开辟空间的情况,
// 还有一种是在循环体内开辟空间,那个简单一点,最后不用free了(如果是head == NULL,还是要free一下)。
}


[ 本帖最后由 神机军师 于 2014-4-10 19:34 编辑 ]

未知令人期待!
2014-04-10 19:30
快速回复:刚开始接触链表,看了许多创建方面的,但是还是有点疑惑!!!!!!! ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.046257 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved