数据结构中双向链表的基本操作(源代码)

#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;
} 

猜你喜欢

转载自blog.csdn.net/weixin_40908734/article/details/79215693
今日推荐