【数据结构】双链表的实现(C语言)

双链表中的结点包括3个域,一个是存放数据信息的info域,另两个是指阵域,这里用llink和rlink表示,llink指向它的前驱结点,rlink指向它的后继结点。

【数据结构】双链表的实现(C语言)_第1张图片

双链表要掌握以下基本操作:

1、创建一个空的双链表。

2、输出双链表中各结点的值。

3、在双链表中查找第i个结点。

4、在双链表中第i个结点后插入一个值为x的新结点。

5、双链表中删除一个结点。

运行环境:Dev-C++5.11

以下是头文件

#ifndef D_HEAD_LINK_H_INCLUDED
#define D_HEAD_LINK_H_INCLUDED
#include 
#include  
typedef struct dlink_node
{
	int info;
	struct dlink_node *llink,*rlink;
}DN;

/*建立一个空的双链表*/
DN *init()
{
	return NULL;
}


/*对双链表进行初始化*/
DN *creat(DN *head)
{
	DN *p,*q,*h=head;
	int x;
	printf("\n以输入-1作为结束\n");
	scanf("%d",&x);
	while(x!=-1)
	{
		p=(DN*)malloc(sizeof(DN));
		p->info=x;
		if(!h)
		{
			p->llink=NULL;
			q=p;
			h=p;
		}
		else
		{
			p->llink=q;
			q->rlink=p;
			q=p;
		}
		p->rlink=NULL;
		scanf("%d",&x);
	}
	return h;
} 


/*输出双链表中各个结点的值*/
void display_rlink(DN *head)
{
	DN *p=head; 
	if(!head)
	{
		printf("\n该双链表是空的\n");
	}
	else
	{
		while(p)
		{
			printf("%d  ",p->info);
			p=p->rlink;
		}
	}
} 

/*计算双链表中的结点个数*/
int node_numbers(DN *head)
{
	DN *p=head;
	int count=0;
	if(!p)
	{
		printf("该链表是空链表!\n");
		return 0; 
	}
	else
	{
		while(p)
		{
			count++;
			p=p->rlink;
		}
		return count;
	}
} 


/*查找双链表中第i个结点的值*/
DN *find(DN *head,int i)
{
	int j=1;
	DN *p=head;
	if(i<1)
	{
		printf("第%d个结点不存在\n");
		return NULL;
	}
	else
	{
		while(p && j!=i)
		{
			p=p->rlink;
			j++;
		}
		if(!p)
		{
			printf("第%d个结点不存在\n");
			return NULL;
		}
		else
		{
			return p;
		}
	}
}

/*利用llink逆序输出*/
void display_llink(DN *rear)
{
	DN *p=rear;
	while(p)
	{
		printf("%d  ",p->info);
		p=p->llink;
	}
}

/*在双链表第i个结点后插入一个值为x的新结点*/
DN *insert(DN *head,int i,int x)
{
	DN *p,*q;
	p=(DN*)malloc(sizeof(DN));
	p->info=x;
	if(i<0)
	{
		printf("不存在该结点\n");
		return head; 
	}
	else if(i==0)/*即在第一个结点前插入*/
	{
		p->llink=NULL;
		p->rlink=head;
		if(!head)/*双链表为空*/
		{
			head=p; 
		} 
		else
		{
			head->llink=p;
			head=p;
		}
		return head;
	}
	else
	{
		q=find(head,i);
		if(!q)/*不存在第i个结点*/
		{
			free(p);
			printf("不存在第%d个结点,无法进行插入\n",i);
		}
		else if(q->rlink==NULL)/*在最后一个结点插入*/
		{
			p->rlink=NULL;
			p->llink=q;
			q->rlink=p; 
		} 
		else
		{
			p->llink=q;
			p->rlink=q->rlink;
			q->rlink->llink=p;
			q->rlink=p;	
		}
		return head; 
	}
	
} 

/*在双链表中删除一个值为x的结点*/
DN *dele(DN *head,int x)
{
	DN *p=head;
	if(!head)
	{
		printf("该双链表为空,无法进行删除操作\n");
		return head;
	}
	else
	{
		while(p && p->info!=x)
		{
			p=p->rlink;
		}
		if(!p)/*没有找到要删除的结点*/
		{
			printf("\n没有找到值为%d的结点,无法进行删除操作\n",x);
			return head;
		}
		else
		{
			if(p==head && p->rlink)/*被删除的结点是第一个结点且表中不只一个结点*/
			{
				head=head->rlink;
				head->llink=NULL;
				free(p);
				return head;
			} 
			if(p==head && !head->rlink)
			{
				free(p);
				return NULL;/*双链表置空*/
			}
			else 
			{
				if(!p->rlink)/*被删除的结点是双链表中最后一个结点*/ 
				{
					p->llink->rlink=NULL;
					free(p);
					return head;					
				}
				else/*q是两个以上结点的双链表中的一个非开始也非终端的结点*/
				{
					p->llink->rlink=p->rlink;
					p->rlink->llink=p->llink;
					free(p);
					return head;
				}
			} 
		}
	}
}
#endif // D_HEAD_LINK_H_INCLUDED

以下是主程序

#include "stdio.h"
#include "d_head_link.h"
int main ()
{
	int i,x;
	DN *p,*q,*h,*rear;
	while(1)
	{
		h=init();
		h=creat(h);
		display_rlink(h); 
		printf("一共有%d个结点\n",node_numbers(h));
		rear=find(h,node_numbers(h));
		display_llink(rear);
		printf("一共有%d个结点\n",node_numbers(h));/*利用llink逆序输出*/
		printf("在双链表第i个结点后插入一个值为x的新结点,下面请输入i和x:");
		scanf("%d%d",&i,&x);
		h=insert(h,i,x);
		display_rlink(h);
		printf("在双链表中删除一个值为x的结点,下面请输入x:");
		scanf("%d",&x);
		h=dele(h,x);
		display_rlink(h);
	}
	return 0;
}

运行结果:

【数据结构】双链表的实现(C语言)_第2张图片

我是设置了一个循环,所以无限次的测试下去!!!

你可能感兴趣的:(C/C++)