双向链表的相关操作

双向链表的相关操作

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
typedef struct LinkListNode
{
	int data;
	struct LinkListNode* prior;
	struct LinkListNode* next;
}node,*LinkList;  //结构体变量类型

void  GreatLinklistTail(LinkList* head); // 建立链表
void LinkListInsert(LinkList* head); //插入节点
void LinkListFind(LinkList* head); //查找数据 
void LinkListnode_Delete(LinkList* head); //删除节点
void LinkListDatePrint(LinkList* head);  //链表的输出
void LinkListClean(LinkList* head);   //链表的整表删除 
/**
*为了建立、使用、维护链表,对链表的操作如下:
*建立链表
*遍历链表
*尾部追加
*删除结点
*查找结点
*/
/******************************************************************************/
int main(void)
{
	LinkList head;
	int i;
	printf("*************************双向链表操作***************************\n\n");
	printf("1.初始化双向链表\n\n2.插入节点 \n\n3.删除节点 \n\n4,查找节点\n\n0.释放内存操作完成\n\n"); 
	while(1)
	{
		scanf("%d", &i);
		switch(i)
		{
		
			case 1:
				{
					printf("下面进行建立双向链表操作!\n"); 
					GreatLinklistTail(&head);
					LinkListDatePrint(&head);
				}
				break;
			case 2:
				{
					printf("下面进行插入节点操作!\n"); 
					LinkListInsert(&head);
					LinkListDatePrint(&head);
				}
				break;
			case 3:
				{ 
				printf("下面进行建立删除节点操作!\n"); 
				LinkListnode_Delete(&head);
				LinkListDatePrint(&head);
				} 
				break;
			case 4:
				{
					printf("下面进行查找数据操作!\n"); 
					LinkListFind(&head);
				} 
				break;
			
		}
		if(i == 0)
		{
			break;
		}
	}
	printf("双向链表操作结束!\n"); 
	LinkListClean(&head);
	system("pause"); 
	return 0;
}
/**********************************************************************************/

//双向链表初始化操作 
void GreatLinklistTail(LinkList* head)
{
	node *p, *q = NULL;   //声明节点p 和q 
	int i, j;
 
	*head = (LinkList)malloc(sizeof(LinkList)); //为第一个节点开辟内存 
	(*head)->next = NULL;  //将第一个结构体指针的的next 指向第一个节点 
	(*head)->prior = NULL; // 将第一个结构体指针的的prior指向第一个节点 
	
	p = *head;
	printf("请输入所要开辟节点的个数,输入0退出: \n");
	scanf_s("%d", &i);
	fflush(stdin);

	if(i == 0)
	{
		return ;  //如果输入 0直接退出程序 
	}
		
	else
	{	
		
		p = *head;  //令p指向第一个节点 便于操作
		for (j = 1; j <= i; j++)
		{
			if(j == 1)  //开辟第一个节点时 
			{	
				printf("请输入第%d个节点所要存储的数据:", j);
				scanf_s("%d", &p->data); 
				fflush(stdin);
				p->next = NULL;
				p->prior = NULL;
			}
			else
			{
				q = (node*)malloc(sizeof(node));  //为q 开辟内存 
				
				if (!q)
				{
					return;  //分配内存失败退出  
				}
				
				printf("请输入第%d个节点所要存储的数据:", j);
				scanf_s("%d", &q->data);
		 
				q->prior = p;  //q的前驱指针指向 p节点
				q->next = p->next; //将尾节点的next指向 空 
				p->next = q;  // p的next指向 q 
				p = q;		//通过循环建立双向链表 
			} 
		}
	}
	printf("单链表建立完毕!!!\n\n");  
} 

//打印数据函数 
//链表数据的输出 
/*思路:
	1,开辟一个节点p
	2,令节点p指向第一个节点
	3,通过循环打印出每个节点的值
*/
void LinkListDatePrint(LinkList *head)
{
	node *p;
	int j = 1;
	printf("********************链表中的数据********************\n"); 

	p = *head;
	
	while(p)
	{
		printf("第%d个节点存储的数为:%d;\n", j, p->data);
		j++;
		p = p->next;  //循环遍历链表算法 
		 
	}
	printf("链表数据打印完毕!!!\n\n"); 
}

//链表的整表删除
/*思路:
	1,声明节点p,q
	2,将第一个节点赋给p,下一个赋给 q
	3,循环执行释放p和将q赋给p操作
*/
void LinkListClean(LinkList* head)
{
	node* p, * q;

	p = *head;
	while (p)  //循环释放法则 
	{
		q = p->next;
		free(p);
		p = q;
	}  
	
	printf("单链表内存释放成功!!!\n");
}

//链表的数据插入操作

void LinkListInsert(LinkList* head) //插入节点
{
	node *p, *s;  //声明循环遍历结构体指针p 和 插入节点 s 
	int i, j = 1;

	s = (node*)malloc(sizeof(node));  //为要插入的节点开辟内存  
	
	s->next = NULL;  //防止成为野指针
	s->prior = NULL;
	
	printf("请输入要插入的节点的位置:");
	scanf_s("%d", &i);
	fflush(stdin);
	
	if(i == 1)
	{
		printf("请输入插入节点存储的值:");
		scanf("%d", &s->data);
		fflush(stdin);
		
		s->next = *head;
		(*head)->prior = s;
		s->prior = NULL;
	}
	else
	{
		printf("请输入插入节点存储的值:");
		scanf("%d", &s->data);
		fflush(stdin);
		
		for(p = *head, j = 1; j < i && p; j++)
		{
			p = p->next;
		}
		
		s->next = p;
		s->prior = p->prior;
		p->prior->next = s;
		p->prior = s;
		
	}
	printf("节点插入成功!!!\n\n"); 
}
//节点的查找并返回节点的位置 
/*
思路:
	1,声明节点 p,开辟节点,指向头结点
	2, 声明计数器j 和存储数据的 容器
	3, 循环查找
*/
void LinkListFind(LinkList* head)  //查找第i个元素
{
	node *target;
	int  i, j = 1;

	printf("请输入查找的数据:");
	scanf_s("%d", &i);
	fflush(stdin);

	for (target = *head; target->data != i && target != NULL ; target = target->next)
		j++;   
	printf("该节点的位置是: %d\n\n", j);
}

//单链表节点删除操作
void LinkListnode_Delete(LinkList* head)
{
	node *p;  //声明节点p指向链表的第一个节点
	int i;   //要删除的节点 
	int j = 1; //声明一个计数器  
	p = *head;  //p节点指向第一个节点 

	printf("请输入要删除的节点标号:");
	scanf_s("%d", &i);
	fflush(stdin);

	if (i == 1)
	{
	
		p = *head;  //将p指向第一个节点 
		*head = p->next;  //将第二个节点 赋给*head 
		(*head)->prior = NULL; //第二个节点的prior置空 
		
	 	printf("节点删除成功!!!!\n\n"); 
		free(p);
	}
	else
	{
		for(j = 1; j < i; j++)
		{
			p = p->next;	 //找到第i个节点 
		} 
		
		p->prior->next = p->next;
		p->next->prior = p->prior;  
		free(p);
		
		printf("节点删除成功!!!!\n\n"); 
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

甜不辣-酱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值