| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4342 人关注过本帖
标题:双链表的尾部添加节点问题
只看楼主 加入收藏
lanke711
Rank: 9Rank: 9Rank: 9
来 自:流浪在天国之路
等 级:蜘蛛侠
威 望:7
帖 子:317
专家分:1437
注 册:2015-7-16
结帖率:100%
收藏
已结贴  问题点数:100 回复次数:7 
双链表的尾部添加节点问题
程序代码:
#include <stdio.h>
#include <stdlib.h>

typedef struct list
{
    int data;
    struct list* prior;//前驱节点
    struct list* pnext;//后继节点
}node,*ptrl;

int listcount;//全局变量,链表节点

//建立链表
ptrl createlist()
{
    node* lhead,*lnew,*lend;
    int createnum;
    listcount=0;        //存放数据
    lhead=(node*)malloc(sizeof(node));
    lend=lhead;
    lend->pnext=NULL;
    printf("输入数据:\n");
    while((scanf("%d",&createnum))!=0)
    {
        
        if(createnum==0)
        {
            break;
        }
        listcount++;
        lnew=(node*)malloc(sizeof(node));
        lnew->data=createnum;        //数据存入链表
        if(lhead==NULL)
        {
            lhead=lnew;
            lend=lhead;
        }
        else
        {
            lnew->pnext=lend;
            lnew->prior=lend;
            lend->pnext=lnew;
            lend=lnew;
            
        }
        lend->pnext=NULL;
    }
    return lhead;
}


//在指定节点添加节点数据
ptrl addnum(int num,node* lhead,int listdata)
{
    node *lnew,*temp;    //temp用来遍历到指定节点的LIST指针,lnew用于保存新节点数据
    int addcount=0;
    lnew=(node*)malloc(sizeof(node));
    temp=lhead;
    lnew->data=listdata;
    //在表头插入数据
    if(temp->pnext==NULL)
    {
        
        lnew->pnext=lhead;    
        temp->pnext=lnew->pnext;
        temp->prior=lnew;
        listcount++;
    }
    //如果在表中插入节点数据
    if(temp->pnext!=NULL&&listcount!=num-1)
    {
        while(addcount<num)
        {
            temp=temp->pnext;
            addcount++;
        }
        lnew->pnext=temp;
        lnew->prior=temp->prior;
        temp->prior->pnext=lnew;
        temp->prior=lnew;
        listcount++;
        
    }
    else
    {    //在表尾插入节点数据                            
        for(addcount=0;addcount<num-1;++addcount)
        {
            temp=temp->pnext;
            
        }
        
        listcount++;//链表节点递增一次
        lnew->pnext=temp;    //接入链表
        lnew->prior=temp->prior;
        temp->prior->pnext=lnew;
        temp->pnext=NULL;    
        
    }
    return  lhead;

}
void prit(node* lhead)
{
    node* ltemp;
    ltemp=lhead->pnext;
    if(lhead==NULL)
    {
        printf("空链表");
        exit(-1);
    }
    while(ltemp!=NULL)
    {
        printf("%d\n",ltemp->data);
        ltemp=ltemp->pnext;
    }
}
int main()
{
    node* temp;
    int listnum;//节点
    int listdata;//数据
    temp=(node*)malloc(sizeof(node));
    temp=createlist();
    prit(temp);
    printf("输入要添加的节点:");
    scanf("%d",&listnum);
    printf("输入要添加的数据:");
    scanf("%d",&listdata);
    temp=addnum(listnum,temp,listdata);
    prit(temp);
    return 0;
}


图片附件: 游客没有浏览图片的权限,请 登录注册

调试结果:
图片附件: 游客没有浏览图片的权限,请 登录注册



程序代码:
//如果在表中插入节点数据
    if(temp->pnext!=NULL&&listcount!=num-1)
    {
        while(addcount<num)
        {
            temp=temp->pnext;
            addcount++;
        }
        lnew->pnext=temp;
        lnew->prior=temp;
        temp->prior->pnext=lnew;
        temp->prior=lnew;
        listcount++;
        
    }
    else
    {    //在表尾插入节点数据                            
        for(addcount=0;addcount<num-1;++addcount)
        {
            temp=temp->pnext;
            
        }
        
        listcount++;//链表节点递增一次
        lnew->pnext=temp;    //接入链表
        lnew->prior=temp;
        temp->prior->pnext=lnew;
        temp->pnext=NULL;    
        
    }

想问一下这是哪里出了问题?在表尾添加节点数据,实际运行时却在表尾的前一个节点添加了。。
2016-09-13 20:25
书生牛犊
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:星夜征程
等 级:贵宾
威 望:10
帖 子:1101
专家分:5265
注 册:2015-10-27
收藏
得分:60 
百分贴,非同凡响啊。洒家快看哭了
程序代码:
#include <stdio.h>
#include <stdlib.h>

typedef struct list
{
    int data;
    struct list* prior;//前驱节点
    struct list* pnext;//后继节点
}node,*ptrl;

int listcount;//全局变量,链表节点

//建立链表
ptrl createlist()
{
    node* lhead,*lnew,*lend;
    int createnum;
    listcount=0;        //存放数据
    lhead=(node*)malloc(sizeof(node));//==这里就给lhead盛情空间了,那你应该是造了一个带头结点的链表 后面所有的if(lhead==NULL)都没意义,完全用不上

    lend=lhead;
    lend->pnext=NULL;
    printf("输入数据:\n");
    while((scanf("%d",&createnum))!=0) //有时候scanf()会返回-1,表示EOF,具体的你可以百度一下
    {
       

        if(createnum==0)
        {
            break;
        }
        listcount++;
        lnew=(node*)malloc(sizeof(node));
        lnew->data=createnum;        //数据存入链表
        /*if(lhead==NULL)// 满足不了的条件,可以不要了

        {                //
            lhead=lnew;//
            lend=lhead;//
        }                //
        else*/            //
        {
            lnew->pnext=lend;//新的数据不应该是在lend->next吗怎么lnew->next=lend?你是打算收尾相连做环吗?如果是的话,那前面就不应该造那么一个没用上的头结点

            lnew->prior=lend;//
            lend->pnext=lnew;//
            lend=lnew;
           

        }
        lend->pnext=NULL;//从这一句来看你并不打算把链表收尾相连,那么第四十行lnew->pnext=lend也可以注释掉了。没用!而且还有歧义

    }
    return lhead;
}


//在指定节点添加节点数据
ptrl addnum(int num,node* lhead,int listdata)
{
    node *lnew,*temp;    //temp用来遍历到指定节点的LIST指针,lnew用于保存新节点数据
    int addcount=0;
    lnew=(node*)malloc(sizeof(node));
    temp=lhead;
    lnew->data=listdata;
    //在表头插入数据     //不是应该用num判断一下插入在哪先吗?怎么就“在表头插入数据”了

    if(temp->pnext==NULL)//当temp==NULL的时候你的程序就崩溃了 ,temp->pnext==NULL只有当程序中存在有

    {
       

        lnew->pnext=lhead;   //==lnew->pnext=temp; 什么逻辑?

        temp->pnext=lnew->pnext;//==temp->pnext=lnew->pnext=temp;好吧,恭喜你中奖了!

        temp->prior=lnew;      //lhead不是一个不存放数据的头结点吗?你令lead->prior=lnew,造神马?

        listcount++;          //...

    }
    //如果在表中插入节点数据
    if(temp->pnext!=NULL&&listcount!=num-1)//当程序运行到这里时temp->pnext坑定不为NULL, 不,我已经凌乱了 ,后续代码我就不看了

    {
        while(addcount<num)
        {
            temp=temp->pnext;
            addcount++;
        }
        lnew->pnext=temp;
        lnew->prior=temp->prior;
        temp->prior->pnext=lnew;
        temp->prior=lnew;
        listcount++;
       

    }
    else
    {    //在表尾插入节点数据                          

        for(addcount=0;addcount<num-1;++addcount)
        {
            temp=temp->pnext;
           

        }
       

        listcount++;//链表节点递增一次
        lnew->pnext=temp;    //接入链表
        lnew->prior=temp->prior;
        temp->prior->pnext=lnew;
        temp->pnext=NULL;  

       

    }
    return  lhead;

}
void prit(node* lhead)
{
    node* ltemp;
    ltemp=lhead->pnext;//if (lead==NULL)  程序到这就崩溃了

    if(lhead==NULL)
    {
        printf("空链表");
        exit(-1);
    }
    while(ltemp!=NULL)
    {
        printf("%d\n",ltemp->data);
        ltemp=ltemp->pnext;
    }
}
int main()
{
    node* temp;
    int listnum;//节点
    int listdata;//数据
    temp=(node*)malloc(sizeof(node));
    temp=createlist();
    prit(temp);
    printf("输入要添加的节点:");
    scanf("%d",&listnum);
    printf("输入要添加的数据:");
    scanf("%d",&listdata);
    temp=addnum(listnum,temp,listdata);
    prit(temp);
    return 0;
}





[此贴子已经被作者于2016-9-13 21:23编辑过]


φ(゜▽゜*)♪
2016-09-13 21:18
ehszt
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:40
帖 子:1745
专家分:3216
注 册:2015-12-2
收藏
得分:20 
这里改了一下,调试没问题
     else
     {    //在表尾插入节点数据
        if(listcount!=num-1);
        else
        {
                                                              
        for(addcount=0;addcount<num-1;++addcount)
         {
             temp=temp->pnext;
            
         }
         
         listcount++;//链表节点递增一次
        lnew->prior=temp;    //接入链表
        temp->pnext=lnew;
         lnew->pnext=NULL;   
       }  
     }
2016-09-13 21:23
书生牛犊
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:星夜征程
等 级:贵宾
威 望:10
帖 子:1101
专家分:5265
注 册:2015-10-27
收藏
得分:0 
做了个环,可以输入负数已达到在反向追溯的功能。
程序代码:
#include <stdio.h>
#include <stdlib.h>

typedef struct list {
    int data;
    struct list* prior;//前驱节点
    struct list* pnext;//后继节点
} node,*ptrl;

int listcount;//全局变量,链表节点

//建立链表
node* createlist() {
    node* head=NULL,*lnew,*temp=head;
    int createnum;
    listcount=0;        //存放数据
    printf("输入数据:\n");
    while(scanf("%d",&createnum)==1) {
        if(createnum==0)break;
        listcount++;
        lnew=(node*)malloc(sizeof(node));
        lnew->data=createnum;        //数据存入链表
        if(temp) {
            temp->pnext=lnew;
            lnew->prior=temp;
            temp=lnew;
        } else {
            head=lnew;
            temp=head;
        }
    }
    if(temp) {
        temp->pnext=head;    //令头结点的prior指向链表的最后一个元素,造环
        head->prior=temp;
    }
    return head;
}


//在指定节点添加节点数据
ptrl addnum(int num,node* lhead,int listdata) {
    //temp用来遍历到指定节点的LIST指针,lnew用于保存新节点数据
    node *temp=lhead;
    node *lnew=(node*)malloc(sizeof(node));
    lnew->data=listdata;
    if(lhead==NULL) { //如果链表为空,那么造一个只有一个元素的环
        lnew->prior=lnew;
        lnew->pnext=lnew;
        return lnew;
    }
    if(num<0) {
        for(;num<0;num++)temp=temp->prior;
    }
    for(;num>0;num--)temp=temp->pnext;
        lnew->pnext=temp->pnext;
    lnew->prior=temp;
    temp->pnext->prior=lnew;   
    temp->pnext=lnew;
    return  lhead;
}
void prit(node* lhead) {//由于在这个程序当中我造了一个环,所以输出的时候需要做特别判断

    if(lhead==NULL) {
        printf("空链表");
        return;
    }
    printf("%d\n",lhead->data);//先输出头结点,令temp=head->next;

    node* ltemp=lhead->pnext;
    while(ltemp!=lhead) {//当ltemp回到头结点时停止输出。

        printf("%d\n",ltemp->data);
        ltemp=ltemp->pnext;
    }
}
int main() {
    node* temp;
    int listnum;//节点
    int listdata;//数据
    temp=createlist();
    prit(temp);
    printf("输入要添加的节点:");
    scanf("%d",&listnum);
    printf("输入要添加的数据:");
    scanf("%d",&listdata);
    temp=addnum(listnum,temp,listdata);
    prit(temp);
    return 0;
}





[此贴子已经被作者于2016-9-13 21:57编辑过]


φ(゜▽゜*)♪
2016-09-13 21:52
书生牛犊
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:星夜征程
等 级:贵宾
威 望:10
帖 子:1101
专家分:5265
注 册:2015-10-27
收藏
得分:0 
回复 3楼 ehszt
你先输入一个0,然后再插入试试

φ(゜▽゜*)♪
2016-09-13 21:53
Alien_Lee
Rank: 8Rank: 8
来 自:Linux帝国
等 级:蝙蝠侠
威 望:7
帖 子:149
专家分:739
注 册:2016-7-19
收藏
得分:20 
我接上二楼的吧,你的问题主要是出在对三个位置的判定上。还有就是新旧节点的交替上,
还有两个建议:内存分配不一定成功,如果你非要表明节点的号码,可以将号码写到结构体中去,这样你的后续操作会简单很多

我虽然校正了一些问题,但是不得不说,这个程序还有很大的问题,由于这个问题是逻辑上的问题,改起来就不在是你的程序了。所以共勉吧!有什么问题还可以在问
程序代码:
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

typedef struct list
{
    int data;
    struct list* prior;//前驱节点
    struct list* pnext;//后继节点
}node, *ptrl;

int listcount;//全局变量,链表节点

//建立链表
ptrl createlist()
{
    node* lhead, *lnew, *lend;
    int createnum;
    listcount = 0;        //存放数据
    lhead = (node*)malloc(sizeof(node));
    lend = lhead;
    lend->pnext = NULL;
    printf("输入数据:\n");
    while ((scanf("%d", &createnum)) != 0) //以0作为输入结尾符号
    {

        if (createnum == 0)
        {
            break;
        }
        listcount++;
        lnew = (node*)malloc(sizeof(node));
        lnew->data = createnum;        //数据存入链表
        if (lhead == NULL)
        {
            lhead = lnew;
            lend = lhead;
        }
        else
        {
            //lnew->pnext = lend;
            lnew->prior = lend;
            lend->pnext = lnew;
            lend = lnew;

        }
        lend->pnext = NULL;
    }
    return lhead;
}


//在指定节点添加节点数据
ptrl addnum(int num, node* lhead, int listdata)
{
    node *lnew, *temp;    //temp用来遍历到指定节点的LIST指针,lnew用于保存新节点数据
    int addcount = 0;
    lnew = (node*)malloc(sizeof(node));
    temp = lhead;
    lnew->data = listdata;
    //在表头插入数据
    if (temp->pnext == NULL)
    {
        lnew->pnext = lhead;
        temp->pnext = lnew->pnext;
        temp->prior = lnew;
        listcount++;
    }
    //如果在表中插入节点数据
    if (temp->pnext != NULL&&listcount != num - 1)//这个条件是无法判断它应该插入到表中的
            //不信你输入一个6以上的数『num』,直接就崩溃了
    //如果temp不为空,0<listcount<num-1,应该就能确认为表中,但是前提是以前的表的号码是连续完好的。
    {
        while (addcount<num)
        {
            temp = temp->pnext;
            addcount++;
        }
        //new应该插入到temp前面
        //lnew->pnext = temp;
        lnew->pnext = temp->pnext;
        //lnew->prior = temp->prior;
        lnew->prior = temp;
        //temp->prior->pnext = lnew;
        temp->pnext->prior = lnew;
        //temp->prior = lnew;
        temp->pnext = lnew;
        listcount++;

    }
    else
    {    //在表尾插入节点数据                          
        /*for (addcount = 0; addcount<num - 1; ++addcount)
        {
            temp = temp->pnext;

        }*/
        while (temp->pnext != NULL)//尾部的特征,前提是temp!=NULL
            temp = temp->pnext;

        listcount++;//链表节点递增一次

            //新节点应该在后面
        //lnew->pnext = temp;    //接入链表
        lnew->pnext = NULL;
        //lnew->prior = temp->prior;
        lnew->prior = temp;
        //temp->prior->pnext = lnew;
        temp->pnext = lnew;

    }
    return  lhead;

}
void prit(node* lhead)
{
    node* ltemp;
    ltemp = lhead->pnext;
    if (lhead == NULL)
    {
        printf("空链表");
        exit(-1);
    }
    while (ltemp != NULL)
    {
        printf("%d\n", ltemp->data);
        ltemp = ltemp->pnext;
    }
}
int main()
{
    node* temp;
    int listnum;//节点
    int listdata;//数据
    temp = (node*)malloc(sizeof(node));
    temp = createlist();
    prit(temp);
    printf("输入要添加的节点:");
    scanf("%d", &listnum);
    printf("输入要添加的数据:");
    scanf("%d", &listdata);
    temp = addnum(listnum, temp, listdata);
    prit(temp);
    system("pause");
    return 0;
}




  DEBUG的过程就是进步的过程,每一个小错误都是大问题!...
2016-09-13 22:30
ehszt
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:40
帖 子:1745
专家分:3216
注 册:2015-12-2
收藏
得分:0 
以下是引用书生牛犊在2016-9-13 21:53:35的发言:

你先输入一个0,然后再插入试试

楼主应用if排除空链表的情况。
2016-09-13 22:36
lanke711
Rank: 9Rank: 9Rank: 9
来 自:流浪在天国之路
等 级:蜘蛛侠
威 望:7
帖 子:317
专家分:1437
注 册:2015-7-16
收藏
得分:0 
谢谢各位版主,看完回复我哭了。重新整理思路,重新画流程 重新写过。。。。

普通人之所以普通,是因为他们普遍有一个通病,那就是认为自己永远普通。
千夫所指,我亦坚持。就算被所有人误解,我也照样守护这一切。
我们总是觉得,这些灵魂的表情,傲慢自大,目中无人,其实,真正目中无人的是我们。它们傲慢的不过是表情,而我们傲慢的却是行为!
记得,是为了忘记!
只要想着有那么一天,我就能忍受现在的每一天!
灾难并不可怕,可怕的是心中没有了希望。
你以为我在天堂,其实我正在路上。
当你觉得自己走不到终点的时候,请不要放弃。或许你的对手也是这种感觉。
2016-09-13 22:59
快速回复:双链表的尾部添加节点问题
数据加载中...
 
   



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

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