双向链表 删除节点 插入节点

Attention:

当删除的是倒数第二个节点,仅剩Pm时,Pm->pos=pm->pre=pm ;指向的都是孤立的最后一个节点;

当删除的是最后一个节点时,返回NULL;

当删除的是 其余节点时,返回的是被删除节点的PRE节点。并做好双向指针设置。


打印节点、寻找节点时,均要保存head节点,防止陷入查找死循环。

//双向链表,删除节点,插入节点
#include <stdio.h>
# include<malloc.h>
#include <conio.h>


 typedef struct BiListNode{
	int element;
	BiListNode* Pre;//指向前节点
	BiListNode* Pos;//指向后节点

}node;

 int  insertNode(node* L,int m,int n);
 node* findNode(node* L,int m);
 node* deleteNode(node*L,int m);
 void PrintList(node*L);


int  insertNode(node* L,int m,int n){//在双向链表的m节点后插入n值节点,若无m节点,则在头节点处插入,
	if (L->element==NULL)
	{
		L->element=n;//插入第一个node
		L->Pos=L->Pre=L;//第一个node的前向后向指针均指向自己

	} 
	else
	{   node* Pn=(node*)malloc(sizeof(node));
	    Pn->element=n;
		node* POS=findNode(L,m);//寻找m所在的节点位置
		if(!POS) //未找到m节点,直接插入到头节点后面
		{
			POS=L;
		}
		//找到m节点
		
         node* Ppos=POS->Pos;//m的原始后向节点
		 POS->Pos=Pn;
		 Pn->Pre=POS;
         Pn->Pos=Ppos;//n指向m的原始后向节点
		 Ppos->Pre=Pn;
	}
	return 1;//插入成功 返回1

 }
node* findNode(node* L,int m){//找到m,返回m所在的&node,否则返回Null
	node* head=L;//保存头节点的位置,防止无限循环查找
	if (!L)
	{
		printf("null! The LIST is EMPTY!");
		return NULL;
	}
	if (L->element==m)
	{
		return L;
	} 
	else
	{
		L=L->Pos;
		while(L->element!=m && L!=head){
			L=L->Pos;
		}
		if (L==head)//遍历所有节点,无m
		{
			return NULL;
		} 
		if(L->element==m)//Binggo! 找到m
		{
			return L;
		}
		

	}
	



}
node* deleteNode(node*L,int m){//找到元素m所在的节点,并删除
node* Pm=findNode(L,m);

if (!Pm)//POS==NULL,不存在m
{
	printf("Lucky! NO number%d !\n",m);
	return L;
	
} 
else
{   
	node* PRE=Pm->Pre;
	node* POS=Pm->Pos;
	if(PRE==POS)
	{   if (PRE==Pm)//删除的是最后一个节点
	{
		free(Pm);
		printf("Delete %d succesfully!\n",m);
		printf("the last number in list!\n");
		return NULL;

	} 
	else//删除的是倒数第二个元素
	{
		free(Pm);
		printf("Delete %d succesfully!\n",m);
		PRE->Pos=POS->Pre=PRE;
		return PRE;

	}
		
	}
	else{
		PRE->Pos=POS;
		POS->Pre=PRE;
		free(Pm);
		printf("Delete %d succesfully!\n",m);
		return PRE;
	}
	
	
}


}

void PrintList(node*L){
	node* head=L;//保存入口节点,防止打印陷入死循环
	int flag=1;
	printf("the numbers in the bidirection List:\n");
	if(!L)
		printf("EMPTY list!\n");
	while (L && flag)
	{
		printf("%6d",L->element);
		L=L->Pos;
		flag=(L!=head);
	}
}


int main(){
   node* First=(node*)malloc(sizeof(node));//第一个node
   First->element=NULL;
   First->Pos=First->Pre=NULL;//空节点内容都为NULL;
   printf("Hello,buddy!\n Please input a number:\n ");
   int m=NULL,n=NULL;
   while (scanf("%d",&n))
   {
     if(insertNode(First,m,n))
	 {	m=n;}
	 else
	 {
		 printf("Oops! Insert Failed!\n");
		 break;
	 }    
   }
   while (int c=getchar()!='\n')
   {
    printf("%c %d",c,c);
   }
   /************delete**************/
   printf("buddy! input the number to be deleted:\n ");
   while (scanf("%d",&m))
   {
	   First=deleteNode(First,m);
	   
   }
   /********** Print List  **************/
   PrintList(First);
   getch();
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值