双链表删除指定节点的问题

DePhang 2016-09-05 12:43:34
// doublelist.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include "listheadera.h"

typedef list node;
typedef list* ptrl;
int listcount;

//创建双链表
ptrl screate(node* lhead)
{
listcount = 0;
Elment num;
node* lnew, *lend;
lhead->prior = NULL;
lend = lhead;
lend->pnext = NULL;
printf("输入数据:\n");
while (scanf_s("%d", &num) != 0)
{

if (num == 0)
break;
listcount++;
lnew = (node*)malloc(sizeof(node));
lnew->listnum = num;
if (lhead == NULL) //头节点为空时
{
lnew = lhead;

}
else
{ //头节点不为空时
lnew->pnext = NULL;

lend->pnext = lnew;

}
lend = lnew;

}
lend->pnext = NULL;
return lhead;

}
//查询节点
int findcount(node* lhead,Elment data)
{
node* lnew;
int num=1;
lnew = lhead;
if (lhead == NULL)
{
printf("节点为空!\n");
exit(1);
}
while (lnew!=NULL)
{
num++;
lnew = lnew->pnext;
if (lnew->listnum == data)
{
printf("查询到元素%d,节点为:%d\n",data,num);
break;
}
else
{
printf("没有查询到该元素!\n");
return 0;
}
}
return num;
}

//头节点插入元素
ptrl addhead(node* lhead,Elment data)
{
node* temp,*lnew;
lnew = lhead;
temp = (node*)malloc(sizeof(node));
temp->listnum = data;
if (lnew->pnext == NULL)//当头节点的下一节点为空时,插入数据
{
temp->pnext = NULL;
lnew->pnext = temp;
lnew->prior = temp;
lnew = temp;
}
else
//当有i个循 环节点的时候,需要接入下一节点
{
temp->pnext = lnew->pnext;
lnew->pnext->prior = temp;
temp->prior = lnew;
lnew->pnext = temp;
}
listcount++;
return lhead;
}

//在尾部插入数据
ptrl addend(node* lhead,Elment data)
{
node* lnew, *temp;
int endcount=0;
lnew = lhead;
temp = (node*)malloc(sizeof(node));
temp->listnum = data;
while (endcount<listcount)
{
endcount++;
lnew = lnew->pnext;
}
lnew->pnext = temp;
lnew->pnext->prior = temp;
temp->prior = lnew->pnext;
lnew->pnext->pnext = NULL;
listcount++;
return lhead;
}

//删除指定节点
ptrl dellist(node* lhead, int num)
{
node* deltemp;

deltemp = lhead->pnext;

int delcount=0; //计次变量

while (delcount < num&&deltemp!=NULL)//遍历链表
{
delcount++;
deltemp = deltemp->pnext;

}

if (deltemp == NULL) //如果头节点为空
{
printf("非法操作!\n");
exit(-1);
}
if (deltemp->pnext == NULL)//如果下一节点为空
{
deltemp->prior->pnext = NULL;
free(deltemp);
}
if (deltemp->pnext != NULL)//如果下一节点不为空
{
deltemp->prior->pnext = deltemp->pnext;
deltemp->pnext->prior = deltemp->prior;
free(deltemp);
}
listcount--;
return lhead;
}
//打印
void prit(node* lhead)
{
int pritcount=0;
node* lnew;
lnew = lhead->pnext;
if (lhead == NULL)
{
exit(-1);
}

while (lnew != NULL)
{
pritcount++;
printf("节点%d: ", pritcount);
printf("%d\n", lnew->listnum);
lnew=lnew->pnext;
}
}


int _tmain(int argc, _TCHAR* argv[])
{
node* phead;
Elment maindata,endadd;
int delnum;
phead = (node*)malloc(sizeof(node));
phead=screate(phead);
prit(phead);
printf("\n");
printf("头节点添加数据:\n");
scanf_s("%d",&maindata);
phead=addhead(phead,maindata);
prit(phead);
printf("在尾部添加元素:\n");
scanf_s("%d",&endadd);
phead=addend(phead, endadd);
prit(phead);
printf("输入要删除的节点:\n");
scanf_s("%d",&delnum);
phead=dellist(phead, delnum);
prit(phead);
return 0;
}



求各位前辈指点:删除函数,调试时,删除某个节点直接提示:停止操作。这样的报错
//删除指定节点
ptrl dellist(node* lhead, int num)
{
node* deltemp;

deltemp = lhead->pnext;

int delcount=0; //计次变量

while (delcount < num&&deltemp!=NULL)//遍历链表
{
delcount++;
deltemp = deltemp->pnext;

}

if (deltemp == NULL) //如果头节点为空
{
printf("非法操作!\n");
exit(-1);
}
if (deltemp->pnext == NULL)//如果下一节点为空
{
deltemp->prior->pnext = NULL;
free(deltemp);
}
if (deltemp->pnext != NULL)//如果下一节点不为空
{
deltemp->prior->pnext = deltemp->pnext;
deltemp->pnext->prior = deltemp->prior;
free(deltemp);
}
listcount--;
return lhead;
}
不知道是哪里的错误?
...全文
499 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
DePhang 2016-09-06
  • 打赏
  • 举报
回复
调试了半天。发现前驱节点没有初始化。谢谢!
赵4老师 2016-09-05
  • 打赏
  • 举报
回复
仅供参考:
//不带表头结点的双向链表
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <time.h>
#include <locale.h>
struct NODE {
    int          data;
    struct NODE *next;
    struct NODE *prev;
} *head,*p,*q,*s,*p1,*p2,*q1,**ta;
int i,k,n,t,m,v,N=10;
int main() {
    setlocale(LC_ALL,"chs");
    srand(time(NULL));

    head=NULL;

    printf("创建%d个节点的双向链表:",N);//创建N个节点的双向链表
    p=head;
    for (i=0;i<N;i++) {
        q=(struct NODE *)malloc(sizeof(struct NODE));
        if (NULL==q) exit(1);
        q->data=rand()%100;//填写0..99的随机值
        q->next=NULL;
        q->prev=NULL;
        if (NULL==p) {
            head=q;
            p=head;
        } else {
            p->next=q;
            q->prev=p;
            p=q;
        }
    }

    //输出整个双向链表
    s=head;
    while (1) {
        if (NULL==s) {
            printf("\n");
            break;
        }
        printf("%02d<->",s->data);
        if (NULL!=s->next && s->next->prev!=s) {printf(" !\n");break;}
        s=s->next;
    }

    k=3;
    v=5;
    printf("将值为%d的结点插入到双向链表的第%d个结点前:",v,k);//将值为v的结点插入到双向链表的第k个结点前
    n=0;
    p=head;
    while (1) {
        if (NULL==p) {
            break;
        }
        n++;
        if (k==1) {
            q=(struct NODE *)malloc(sizeof(struct NODE));
            if (NULL==q) exit(1);
            q->data=v;
            q->next=head;
            q->prev=NULL;
            head->prev=q;
            head=q;
            break;
        } else {
            if (k-1==n) {
                q=(struct NODE *)malloc(sizeof(struct NODE));
                if (NULL==q) exit(1);
                q->data=v;
                q->next=p->next;
                q->prev=p;
                p->next->prev=q;
                p->next=q;
                break;
            }
        }
        p=p->next;
    }

    //输出整个双向链表
    s=head;
    while (1) {
        if (NULL==s) {
            printf("\n");
            break;
        }
        printf("%02d<->",s->data);
        if (NULL!=s->next && s->next->prev!=s) {printf(" !\n");break;}
        s=s->next;
    }

    k=5;
    printf("删除第%d个节点:",k);//删除第k个节点
    n=0;
    p=head;
    while (1) {
        if (NULL==p) {
            break;
        }
        n++;
        if (k==1) {
            q=head;
            head=head->next;
            head->prev=NULL;
            free(q);
            break;
        } else {
            if (k-1==n) {
                q=p->next;
                if (q) {
                    p->next=q->next;
                    if (q->next) q->next->prev=p;
                    free(q);
                }
                break;
            }
        }
        p=p->next;
    }

    //输出整个双向链表
    s=head;
    while (1) {
        if (NULL==s) {
            printf("\n");
            break;
        }
        printf("%02d<->",s->data);
        if (NULL!=s->next && s->next->prev!=s) {printf(" !\n");break;}
        s=s->next;
    }

    printf("从小到大排序:");//从小到大排序
    for (p=head,p1=NULL;p!=NULL;p1=p,p=p->next) {
        for (q=p->next,q1=p;q!=NULL;q1=q,q=q->next) {
            if (p->data > q->data) {

                //交换data
//              printf("swap %02d %02d\n",p->data,q->data);
//              t=p->data;p->data=q->data;q->data=t;

                //或者

                //交换prev和next
//              printf("swap %02d %02d\n",p->data,q->data);
                if (p==head) {//p是头
                    if (p->next==q) {//pq挨着
                        head=q;
                        head->prev=NULL;
                        p->next=q->next;
                        p->prev=q;
                        if (q->next) q->next->prev=p;
                        q->next=p;
                        q=p;
                        p=head;
                    } else {//pq不挨着
                        head=q;
                        head->prev=NULL;
                        p2=p->next;
                        p->next=q->next;
                        p->prev=q->prev;
                        if (q->next) q->next->prev=p;
                        q->next=p2;
                        p2->prev=q;
                        q1->next=p;
                        q=p;
                        p=head;
                    }
                } else {//p不是头
                    if (p->next==q) {//pq挨着
                        p1->next=q;
                        p->next=q->next;
                        p->prev=q;
                        if (q->next) q->next->prev=p;
                        q->next=p;
                        q->prev=p1;
                        q=p;
                        p=p1->next;
                    } else {//pq不挨着
                        p1->next=q;
                        p2=p->next;
                        p->next=q->next;
                        p->prev=q->prev;
                        if (q->next) q->next->prev=p;
                        q->next=p2;
                        p2->prev=q;
                        q->prev=p1;
                        q1->next=p;
                        q=p;
                        p=p1->next;
                    }
                }

                //输出整个双向链表
//              s=head;
//              while (1) {
//                  if (NULL==s) {
//                      printf("\n");
//                      break;
//                  }
//                  printf("%02d<->",s->data);
//                  if (NULL!=s->next && s->next->prev!=s) {printf(" !\n");break;}
//                  s=s->next;
//              }
//              getchar();
            }
        }
    }

    //输出整个双向链表并计算链表长度n
    n=0;
    s=head;
    while (1) {
        if (NULL==s) {
            printf("\n");
            break;
        }
        printf("%02d<->",s->data);
        if (NULL!=s->next && s->next->prev!=s) {printf(" !\n");break;}
        n++;
        s=s->next;
    }

    printf("将整个链表逆序:");//将整个链表逆序
    if (n>=2) {
        p=head;
        q=p->next;
        p->next=NULL;
        while (1) {
            q1=q->next;
            q->next=p;
            p->prev=q;
            p=q;
            q=q1;
            if (NULL==q) break;
        }
        head=p;
        head->prev=NULL;
    }

    //输出整个双向链表
    s=head;
    while (1) {
        if (NULL==s) {
            printf("\n");
            break;
        }
        printf("%02d<->",s->data);
        if (NULL!=s->next && s->next->prev!=s) {printf(" !\n");break;}
        s=s->next;
    }

    m=4;
    n=6;
    printf("将双向链表中前%d个结点和后%d个结点进行互换:",m,n);//将双向链表中前m个结点和后n个结点进行互换,m+n为链表总长
    k=0;
    p=head;
    while (1) {
        if (NULL==p) {
            break;
        }
        k++;
        if (m==k) {
            q=p;
        }
        s=p;
        p=p->next;
    }
    q1=head;
    head=q->next;
    head->prev=NULL;
    s->next=q1;
    q1->prev=s;
    q->next=NULL;

    //输出整个双向链表
    s=head;
    while (1) {
        if (NULL==s) {
            printf("\n");
            break;
        }
        printf("%02d<->",s->data);
        if (NULL!=s->next && s->next->prev!=s) {printf(" !\n");break;}
        s=s->next;
    }

    //释放所有节点
    p=head;
    while (1) {
        if (NULL==p) {
            break;
        }
        q=p->next;
        free(p);
        p=q;
    }

    return 0;
}
//创建10个节点的双向链表:93<->03<->60<->05<->57<->71<->02<->41<->26<->85<->
//将值为5的结点插入到双向链表的第3个结点前:93<->03<->05<->60<->05<->57<->71<->02<->41<->26<->85<->
//删除第5个节点:93<->03<->05<->60<->57<->71<->02<->41<->26<->85<->
//从小到大排序:02<->03<->05<->26<->41<->57<->60<->71<->85<->93<->
//将整个链表逆序:93<->85<->71<->60<->57<->41<->26<->05<->03<->02<->
//将双向链表中前4个结点和后6个结点进行互换:57<->41<->26<->05<->03<->02<->93<->85<->71<->60<->
//
DePhang 2016-09-05
  • 打赏
  • 举报
回复
#include "stdafx.h"
#ifndef _LISTHEADERA_H_
#define _LISTHEADERA_H_

typedef int Elment;

struct list
{
	Elment listnum;
	list* prior;
	list* pnext;
};

#endif
头文件的定义
小灸舞 版主 2016-09-05
  • 打赏
  • 举报
回复
看了下发现没啥问题。
要么你把头文件listheadera.h也贴一下
或者自己单步调试,看看是哪句的问题。
单步调试和设断点调试(VS IDE中编译连接通过以后,按F10或F11键单步执行,按Shift+F11退出当前函数;在某行按F9设断点后按F5执行停在该断点处。)是程序员必须掌握的技能之一。
paschen 2016-09-05
  • 打赏
  • 举报
回复
你给一半代码别人没法帮你调试 出错时点中断,断下来通过调用堆栈、变量窗口观察分析原因,必要时可单步跟踪程序运行

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧