Data structure - doubly linked list (7)

data structure


foreword

The doubly-linked list is similar to the singly-linked list, just modify it directly on the basis of the code of the singly-linked list (initialization, insertion, deletion)

1. Double linked list initialization

insert image description here
The two-way pointer is different from the single-phase pointer, it needs one more forward pointer, and then initialize it to NULL

typedef int DataType;
typedef struct ListNode
{
    
    
	DataType a;
	struct ListNode *next;
	struct ListNode *prior;
}ListNode;
//初始化 
int BuyListNode(ListNode **h)
{
    
    
	*h = (ListNode*)malloc(sizeof(ListNode));
	(*h)->next = NULL;
	(*h)->prior = NULL;
	return 1;
}

insert image description here

Second, the insertion of the doubly linked list

int charu(ListNode *h,int p,int n)
{
    
    
	if(NULL==h)
	printf("NULL");
	//把指针移动到要插入位置的前一个位置
	ListNode *q=h; //q等于头指针 
	int k=1;
	while (k<p && q) //防止位置P太大,程序挂掉 
	{
    
    
	q=q->next;//头指针指向的下一个是要插入的前一个位置也就是指针域 
	k++;
	}
  //判断位置是否合法
  if(q==NULL||k>p)
  {
    
    
  	 printf("位置不合法");
  }
  ListNode *m=(ListNode*)malloc(sizeof(ListNode));  //申请一个新的节点
  //插入数据 
  m->a=n;  //新节点的数据域等于插入的数 
  m->next=q->next;//新节点的指针域等于上一个节点的指针域也就是q->next 
  m->prior=q; //此时新的节点指向前一个节点 
  if(q->next)// q->next不为空才执行这个语句 
  q->next->prior=m; //后一个节点指向新的节点 
  q->next=m;//这个时候最开始节点的指针域要修改成现在的节点 
  printf("在第%d个位置插入了%d\n",p,n); 
}

insert image description here

3. Deletion of doubly linked list

//删除 
void shanchu(ListNode *h,int p)
{
    
    
	if (h==NULL)
	printf("NULL");
	//这部分与插入一样,不管插入还是删除都要将指针移动到要删除的前一个位置 
	ListNode *q=h; //q等于头指针 
	int k=1;
	while (k<p && q) //防止位置P太大,程序挂掉 
	{
    
    
	q=q->next;//头指针指向的下一个是要插入的前一个位置也就是指针域 
	k++;
	}
  //判断位置是否合法
  if(q==NULL||k>p)
  {
    
    
  	 printf("位置不合法");
  }
  ListNode *n=q->next;//定义一个新的节点 
  q->next=n->next; //前一个节点的指针域等于新节点的指针域
  if(n->next) 
  n->next->prior=q;//后一个节点指向要删除的前一个节点 
  free(n);
  printf("删除第%d个位置\n",p); 
}

insert image description here

Summarize

insert image description here

//双向链表 
#include<stdio.h>
typedef int DataType;
typedef struct ListNode
{
    
    
	DataType a;
	struct ListNode *next;
	struct ListNode *prior;
}ListNode;
//初始化 
int BuyListNode(ListNode **h)
{
    
    
	*h = (ListNode*)malloc(sizeof(ListNode));
	(*h)->next = NULL;
	(*h)->prior = NULL;
	return 1;
}
int charu(ListNode *h,int p,int n)
{
    
    
	if(NULL==h)
	printf("NULL");
	//把指针移动到要插入位置的前一个位置
	ListNode *q=h; //q等于头指针 
	int k=1;
	while (k<p && q) //防止位置P太大,程序挂掉 
	{
    
    
	q=q->next;//头指针指向的下一个是要插入的前一个位置也就是指针域 
	k++;
	}
  //判断位置是否合法
  if(q==NULL||k>p)
  {
    
    
  	 printf("位置不合法");
  }
  ListNode *m=(ListNode*)malloc(sizeof(ListNode));  //申请一个新的节点
  //插入数据 
  m->a=n;  //新节点的数据域等于插入的数 
  m->next=q->next;//新节点的指针域等于上一个节点的指针域也就是q->next 
  m->prior=q; //此时新的节点指向前一个节点 
  if(q->next) //q->next不为空才执行这个语句 
  q->next->prior=m; //后一个节点指向新的节点 
  q->next=m;//这个时候最开始节点的指针域要修改成现在的节点 
  printf("在第%d个位置插入了%d\n",p,n); 
}
void listprintf(ListNode *h) 
{
    
    
	ListNode *q=h->next; //q指向第一个节点 
	while (q)
	{
    
    
		printf("%d\n",q->a);
		q=q->next;
	 } 
}
//判断链表是否为空,不为空计算出长度 
void listlen(ListNode *h)
{
    
    
	if(h==NULL) 
	printf("链表为空\n");
	else
	printf("链表不为空\n"); 
	ListNode *q=h->next;
	int len=0;
	while(q)
	{
    
    
		len++;
		q=q->next;
	}
	printf("长度为%d\n",len);
}
//查找链表(给定一个数返回这个数的位置) 
void chazhao(ListNode *h,int p) 
{
    
    
	ListNode *q=h->next;
	int i=0,len=0;
while(q)
{
    
    
	len++;
	if(q->a==p)
	{
    
    
		i=len;
	}
	q=q->next;
}
if(i!=0)
printf("%d的位置是%d\n",p,i);
if(i==0)
printf("%d没找到\n",p); 
}
//删除 
void shanchu(ListNode *h,int p)
{
    
    
	if (h==NULL)
	printf("NULL");
	//这部分与插入一样,不管插入还是删除都要将指针移动到要删除的前一个位置 
	ListNode *q=h; //q等于头指针 
	int k=1;
	while (k<p && q) //防止位置P太大,程序挂掉 
	{
    
    
	q=q->next;//头指针指向的下一个是要插入的前一个位置也就是指针域 
	k++;
	}
  //判断位置是否合法
  if(q==NULL||k>p)
  {
    
    
  	 printf("位置不合法");
  }
  ListNode *n=q->next;//定义一个新的节点 
  q->next=n->next; //前一个节点的指针域等于新节点的指针域
  if(n->next) 
  n->next->prior=q;//后一个节点指向要删除的前一个节点 
  free(n);
  printf("删除第%d个位置\n",p); 
}
void fanzhuan(ListNode *h)
{
    
    
	ListNode *p=h->next;
	h->next=NULL;
	while(p)
	{
    
    
		ListNode *q=p;
		p=p->next;
		q->next=h->next;
		h->next=q;
	}
}
void qianqu(ListNode *h,int n,int *p) 
{
    
    
	ListNode *k=h->next; //第一个节点 
	ListNode *q=k->next; //第二个节点
	int r=0;
	while(q)
	{
    
    
		if(q->a==n)
		{
    
    
			*p=k->a;
			r=1;
		}
		q=q->next;
		k=k->next;
	 } 
	 if(r==1)
	 printf("%d的前驱为%d\n",n,*p);
	 else
	 printf("%d没有前驱\n",n);
}
void qingkong(ListNode *h)
{
    
    
	ListNode *p=h->next;
	while(p)
	{
    
    
	h->next=p->next;//把第二个节点的指针域给头节点指针域
	free(p);
	p=h->next;	
    }
    printf("清空成功\n");
}
int xiaohui(ListNode **h) //清空之后才能调用销毁 
{
    
    
	int c=0;
	if((*h)->next!=NULL)
	{
    
    
	
	printf("没有清空链表\n"); 
    c=1;
    printf("销毁失败\n"); 
}
if(c==0)
{
    
    

	free(*h);
	*h=NULL; 
	printf("销毁成功\n");
}
 } 
int main()
{
    
    
	int p;
   //定义一个头指针
	ListNode *head=NULL; 
	int ret=BuyListNode(&head);
	if(ret==1)
	printf("双链表初始化成功\n");
	charu(head,1,1);
	charu(head,2,3);
	charu(head,3,99);
	charu(head,4,2);
	listprintf(head);
	listlen(head);
	chazhao(head,2);
	chazhao(head,5);
	shanchu(head,3);
	listprintf(head);
	shanchu(head,2);
	listprintf(head);
	shanchu(head,2);
	listprintf(head);
	fanzhuan(head);
	printf("链表反转成功\n"); 
	listprintf(head);
	qianqu(head,2,&p);
	qianqu(head,1,&p);
//	qingkong(head);
	listprintf(head);
    xiaohui(&head);
    listprintf(head);
    qingkong(head);
    listprintf(head);
    xiaohui(&head);
    listprintf(head);
} 

Guess you like

Origin blog.csdn.net/qq_51963216/article/details/128812867