#include <stdio.h>
#include <stdlib.h>
typedef int Elemtype;
typedef struct Node{
Elemtype data;
struct Node *prior; //前驱指针
struct Node *next; //后继指针
}Node,*LinkList;
//创建头结点
void create_ListHead(LinkList *pHead) //初始化链表必须用二级指针 这里省略对指针参数的检查
{
*pHead=(LinkList)malloc(sizeof(Node));
if(NULL!=pHead)
{
(*pHead)->next=*pHead;
(*pHead)->prior=*pHead;
}
else
printf("开辟内存失败\n");
}
//创建新结点
LinkList get_newNode(Elemtype e)
{
LinkList newNode=(LinkList)malloc(sizeof(Node));
if(NULL!=newNode)
{
newNode->data=e;
newNode->prior=NULL;
newNode->next=NULL;
return newNode;
}
else
{
printf("开辟内存失败\n");
return 0;
}
}
//头插
void push_Front(LinkList *L,Elemtype e)
{
LinkList p;
p=get_newNode(e);
p->prior=*L;
p->next=(*L)->next;
p->next->prior=p;
p->prior->next=p;
}
//尾插
void push_Back(LinkList *L,Elemtype e)
{
LinkList tail,p;
tail=*L;
while(tail->next!=*L) //让tail指向最后一个结点,注意判断条件
tail=tail->next;
p=get_newNode(e);
p->prior=tail;
p->next=*L;
p->next->prior=p;
p->prior->next=p;
}
//指定位置插入
void insert_List(LinkList *L,int i,Elemtype e)
{
LinkList q=*L; //q指向插入位置的前一个结点
int count=1; //计数
while(count<i && q->next!=*L)
{
q=q->next;
count++;
}
if(count!=i)
{
printf("The position is wrong\n");
return;
}
LinkList p=get_newNode(e);
p->prior=q; //先搞定插入结点的前驱后继
p->next=q->next;
p->next->prior=p; //再搞定后结点的前驱和前结点的后继
p->prior->next=p;
}
//头删
void pop_Front(LinkList *L)
{
LinkList p;
p=(*L)->next;
if(p!=*L)
{
(*L)->next=p->next;
p->next->prior=*L;
free(p);
p=NULL; //养成释放内存后将指针赋值成空的习惯,防止其成为野指针
printf("OK\n");
}
}
//尾删
void pop_Back(LinkList *L)
{
LinkList p;
p=*L;
while(p->next!=*L)
p=p->next;
p->prior->next=*L;
(*L)->prior=p->prior;
free(p);
p=NULL;
printf("OK\n");
}
//指定元素删除
void delete_List(LinkList *L,Elemtype key)
{
LinkList p;
p=(*L)->next;
while(p!=*L)
{
if(p->data==key)
{
p->next->prior=p->prior;
p->prior->next=p->next;
free(p);
p=NULL;
printf("删除成功\n");
return;
}
else
p=p->next;
}
printf("data not found\n");
}
//正逆向打印
void print_List(LinkList *L)
{
LinkList p;
p=(*L)->next;
if(p==*L)
printf("NULL\n");
else
{
while(p!=*L)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
p=p->prior;
while(p!=*L)
{
printf("%d ",p->data);
p=p->prior;
}
printf("\n");
}
}
//求长度
int length_List(LinkList *L)
{
LinkList p=(*L)->next;
int length=0;
while(p!=*L)
{
length++;
p=p->next;
}
return length;
}
//查找
int search_List(LinkList *L,Elemtype e)
{
LinkList p=(*L)->next;
int i=1;
while(p!=*L)
{
if(p->data==e)
return i;
else
p=p->next;
i++;
}
printf("data not found\n");
return 0;
}
//整表删除 (留了头结点)
void destory_List(LinkList *L)
{
LinkList p,q;
p=(*L)->next;
while(p!=*L)
{
q=p->next;
free(p);
p=q;
}
(*L)->next=*L;
printf("OK\n");
}
int main()
{
LinkList L;int e,i,temp;
while((i=getchar())!='#') //输入#退出循环
{
switch(i)
{
case '0':create_ListHead(&L);break;
case '1':printf("输入插入的位置及元素\n");
scanf("%d %d",&temp,&e);
insert_List(&L,temp,e);
break;
case '2':printf("输入插入表尾的值\n");
scanf("%d",&e);
push_Back(&L,e);
break;
case '3':printf("输入插入表头的值\n");
scanf("%d",&e);
push_Front(&L,e);
break;
case '4':pop_Front(&L);break;
case '5':pop_Back(&L);break;
case '6':print_List(&L);break;
case '7':printf("输入删除的值\n");
scanf("%d",&e);
delete_List(&L,e);
break;
case '8':printf("长度为%d\n",length_List(&L));break;
case '9':printf("输入查找的值\n");
scanf("%d",&e);
temp=search_List(&L,e);
if(temp!=0)
printf("%d在第%d个位置\n",e,temp);
break;
case 'd':destory_List(&L);break;
}
}
destory_List(&L);
free(L);
L=NULL;
return 0;
}
数据结构中双向链表的基本操作(源代码)
最新推荐文章于 2024-08-21 14:19:15 发布