阿涛,你要认真对待每一件事,你要潇洒,你要做自己!
前面复习了单向链表和循环链表的操作,写得比较乱,现在写个比较规整的双向链表的的各项操作。
先上个截图:
双向链表的定义和好处我就不说了,说的再好也没有百度说的好,呵呵,何必再去浪费优快云的服务器空间呢。
全部代码如下:
#include <stdio.h>
#include <stdlib.h>
#define LEN sizeof(struct DoubleLinkList)
typedef struct DoubleLinkList
{
struct DoubleLinkList *previous;
int num;
struct DoubleLinkList *next;
}DB,*PDB;
void printInfo();
void CreatDoubleLinkList(int headNum);
void CreatNewDot(PDB *newDot,int num);
PDB SearchDot(int num);
void InsertDot(PDB dot,int AfterNum);
void DeleteDot(int num);
void ChangeDot(int originNum,int changeNum);
void DeleteAll();
PDB Head=NULL;
PDB newDot=NULL;
int inputNum=0;
int chanNum=0;
int order=-1;
int main()
{
do
{
printf("***********************命令菜单***************************\n");
printf("*** ***\n");
printf("***********************1:创建双向链表头节点***************\n");
printf("*** ***\n");
printf("***********************2:创建新节点***********************\n");
printf("*** ***\n");
printf("***********************3:改变节点值***********************\n");
printf("*** ***\n");
printf("***********************4:删除节点*************************\n");
printf("*** ***\n");
printf("***********************5:打印现在列表的值*****************\n");
printf("*** ***\n");
printf("***********************6:释放链表所有节点*****************\n");
printf("*** ***\n");
printf("***********************7:退出程序*************************\n");
printf("请输入命令:\n");
scanf("%d",&order);
switch(order)
{
case 1:
printf("请输入头结点的值:\n");
scanf("%d",&inputNum);
CreatDoubleLinkList(inputNum);
break;
case 2:
printf("请输入新结点的值:\n");
scanf("%d",&inputNum);
CreatNewDot(&newDot,inputNum);
printf("请输入你要插在那个节点之后:\n");
scanf("%d",&inputNum);
InsertDot(newDot,inputNum);
break;
case 3:
printf("请输入要改变的节点的原来的值:\n");
scanf("%d",&inputNum);
printf("请输入要改变后值:\n");
scanf("%d",&chanNum);
ChangeDot(inputNum,chanNum);
break;
case 4:
printf("输入要删除的节点的值:\n");
scanf("%d",&inputNum);
DeleteDot(inputNum);
break;
case 5:
printInfo();
break;
case 6:
DeleteAll();
break;
default:
break;
}
}while(order!=7);
return 0;
}
void printInfo()
{
if(Head==NULL)
{
printf("链表为空!\n");
return ;
}
PDB pOut=Head;
printf("链表值为:\n");
do{
printf("%d\n",pOut->num);
pOut=pOut->next;
}while(pOut->next!=Head->next);
}
void CreatDoubleLinkList(int headNum)
{
Head=(PDB)malloc(LEN);//必须申请内存空间,不然报错,如果没有初始化为NULL,又没有分配空间,后果和严重,令CodeBlocks休克了
Head->num=headNum;
Head->next=Head->previous=Head;
printf("双向链表的头结点已经创建,值为:%d\n",Head->num);
}
void CreatNewDot(PDB *newDot,int number)
{
//指针作为参数,为指针参数申请内存空间,
//必须使用双指针,实参为指针的引用,
//否则参数指针不会被分配空间,并且引起内存泄露,无法free掉
(*newDot)=(PDB)malloc(LEN);
(*newDot)->num=number;
}
PDB SearchDot(int num)
{
if(Head==NULL)
{
printf("链表为空,没有可以删除的节点!\n");
return NULL;
}
else if(Head->num==num)
{
return Head;
}
else
{
PDB search=Head->next;
while(search->num!=num&&search!=Head)
{
search=search->next;
}
if(search==Head)
return NULL;
else
return search;
}
return NULL;
}
void InsertDot(PDB dot,int AfterNum)
{
if(dot==NULL)
return ;
else
{
PDB AfterDot=SearchDot(AfterNum);
dot->previous=AfterDot;
dot->next=AfterDot->next;
AfterDot->next->previous=dot;
AfterDot->next=dot;
}
printf("数据插入成功!\n");
}
void DeleteDot(int num)
{
PDB delDot=SearchDot(num);
if(delDot==NULL)
{
printf("节点不存!\n");
return ;
}
delDot->previous->next=delDot->next;
delDot->next->previous=delDot->previous;
free(delDot);
printf("节点删除成功!\n");
}
void ChangeDot(int originNum,int changeNum)
{
PDB chanDot=SearchDot(originNum);
if(chanDot==NULL)
{
printf("不存在节点值为:%d 的节点!\n",originNum);
return ;
}
else
{
chanDot->num=changeNum;
printf("节点值更改成功!\n");
}
}
void DeleteAll()
{
if(Head==NULL)
{
printf("链表为空,不需要释放!\n");
return ;
}
PDB del=NULL;
while(Head->next!=Head)
{
del=Head->next;
Head->next=del->next;
del->next->previous=Head;
free(del);
}
if(Head!=NULL)
free(Head);
Head=NULL;
printf("链表释放完毕!");
}
有不对的地方请大家指正,有疑问请给阿涛留言,谢谢!