双链表
定义
双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。
简单图示
简单介绍
这次写的双链表的头结点是不储存数据的,所有数据都是存于头结点的下一个结点,即所有判断都以头结点的下一个结点为准。
数据简介
typedef struct dnode
{
char name[15];
int age;
struct dnode *pre; //前驱
struct dnode *next; //后继
} Link;
函数简介
Link *creat() //创建双链表
void deleteAll(Link *target) //清空链表
void reverse(Link *target) //逆置链表
void length(Link *target) //链表长度
void print(Link *target) //遍历 (正向遍历)
void isEmpty(Link *target) //判空
void search(Link *target) //搜索数据 按年龄查找 (正向查找)
void insert(Link *target) //指定位置插入数据
void delete(Link *target) //指定位置删除数据
代码
#include<stdio.h>
#include<malloc.h>
typedef struct dnode
{
char name[15];
int age;
struct dnode *pre; //前驱
struct dnode *next; //后继
} Link;
//创建双链表 首结点不存数据
Link *creat()
{
Link *head=(Link*)malloc(sizeof(Link));
head->pre=NULL; //将头结点前驱置空
Link *p1,*p2;
p1=head;
p2=(Link*)malloc(sizeof(Link));
scanf("%s %d",p2->name,&p2->age);
while(p2->name!=NULL && p2->age>=0)
{
p1->next=p2;
p2->pre=p1;
p1=p2;
p2=(Link*)malloc(sizeof(Link));
scanf("%s %d",p2->name,&p2->age);
}
p1->next=NULL;
return head;
}
//清空链表
void deleteAll(Link *target)
{
Link *p=target->next; //保留头结点
while(p)
{
Link *tmp=p;
p=p->next;
free(tmp);
}
target->next=NULL;
printf("Delete List Completed !!\n");
}
//逆置链表
void reverse(Link *target)
{
Link *p1,*p2,*p3;
p1=target->next;
target->next=NULL;
if(p1==NULL) //判断是否为空表,是则终止以下步骤
{
printf("The List is void !\n");
return ;
}
while(p1) //后面的结点不断往头结点后插入
{
p2=p1;
p1=p1->next;
p2->pre=p1;
p2->next=target->next;
target->next=p2;
}
p2->pre=target; //将最后一个结点的前驱指向头结点
printf("Reverse Completed !\n");
}
//链表长度
void length(Link *target)
{
Link *p=target->next;
int n=0;
while(p)
{
n++;
p=p->next;
}
printf("The List length is :%d\n",n);
}
//遍历 (正向遍历)
void print(Link *target)
{
Link *p=target->next;
if(!p)
{
printf("The List is void !\n");
return ;
}
printf("\nThe List is :\n");
while(p)
{
printf("%s\t%d\n",p->name,p->age);
p=p->next;
}
printf("Print Completed !\n");
}
//判空
void isEmpty(Link *target)
{
Link *p=target->next;
if(p)
printf("Is true !\n");
else
printf("Is void !\n");
}
//搜索数据 按年龄查找 (正向查找)
void search(Link *target)
{
Link *p=target->next;
if(p) //判空
{
int age;
printf("Please input the age for searching :\n");
scanf("%d",&age);
int n=1; //作为是否查到得到的标志
while(p) //遍历链表
{
if(age==p->age) //查找到数据就终止遍历
{
break;
}
n++; //记录索引
p=p->next;
}
if(!p) //判断是否查找到
printf("can not find data !\n");
else
printf("find the data ! In NO.%d \n",n);
}
else
{
printf("The List is void !\n");
}
}
//指定位置插入数据
void insert(Link *target)
{
int pos;
printf("Please input insert position:\n");
scanf("%d",&pos);
if(pos<1) //判断位置索引是否有误
{
printf("Position Error !\n");
return ;
}
int n=1;
Link *p;
Link *data=(Link*)malloc(sizeof(Link)); //新插入的结点
p=target->next;
while(p) //定位
{
if(n>=pos) //p为需要插入的位置
break;
n++;
p=p->next;
}
if(p==NULL) //判断是否超出链表长度
{
printf("Position Error !\n");
return ;
}
printf("Please input new data (name and age) :\n");
scanf("%s %d",data->name,&data->age);
data->pre=p->pre;
p->pre->next=data;
data->next=p;
p->pre=data;
printf("Insert Completed !\n");
}
//指定位置删除数据
void delete(Link *target)
{
int pos;
printf("Please input delete position:\n");
scanf("%d",&pos);
if(pos<1) //判断位置索引是否有误
{
printf("Position Error !\n");
return ;
}
int n=1;
Link *p=target->next;
while(p) //定位
{
if(n>=pos) //p为需要删除的位置
break;
n++;
p=p->next;
}
if(p==NULL) //判断是否超出链表长度
{
printf("Position Error !\n");
return ;
}
p->pre->next=p->next;
if(p->next!=NULL) //判断p是否为最后一个结点,若是则不用执行
p->next->pre=p->pre;
free(p);
printf("Delete Coompleted !\n");
}
//测试
int main()
{
Link *List=NULL;
int n;
while(1)
{
printf("\n****************************************************\n");
printf(" 1.创建链表\t2.判断是否为空\t3.遍历运算\n");
printf(" 4.指定位置插入\t5.指定位置删除\n");
printf(" 6.指定数据搜索\t7.逆置 \t\t8.置空\n");
printf(" 9.输出长度 \t\t\t0.exit\n");
printf("****************************************************\n");
fflush(stdin);
scanf("%d",&n);
switch(n)
{
case 0:
exit(0);break;
case 1:
List=creat();break;
case 2:
isEmpty(List);break;
case 3:
print(List);break;
case 4:
insert(List);break;
case 5:
delete(List);break;
case 6:
search(List);break;
case 7:
reverse(List);break;
case 8:
deleteAll(List);break;
case 9:
length(List);break;
default:
printf("重新输入\n");
}
}
}