王道2-9 双向链表插入删除遍历

1.结构体定义和初始化

init函数:
头结点申请空间(L为空申请失败), 把next prior 设为空

//双向链表的类型定义
typedef struct DLNode{
	int data;
	struct DLNode *prior,*next;
}DLNode,*DLinkList;

//双向链表的初始化
bool InitDLinkList(DLinkList &L){
	L=(DLNode*)malloc(sizeof(DLNode));	//分配一个头结点
	if(L==NULL)
		return false;		//内存分配失败
	L->prior=NULL;			//为空
	L->next=NULL;			//为空
	return true;
}

2.插入

(1).p后插入s ------- p和s不为空
(2).分四步,先连后面后连前面;
(3).注意边界条件,插入到最后位置 即插入的结点的next if(p->next!=NULL)
在这里插入图片描述代码:

//p结点后插入s结点
bool InsertNextNode(DLNode *p,DLNode *s){
	if(p==NULL||s==NULL)		//参数非法
		return false;
	s->next=p->next;  //1
	if(p->next!=NULL)	//插入的那个点->next不为空		
		p->next->prior=s;//2
	s->prior=p;      //3
	p->next=s;      //4
	return true;
	//先写后两个箭头
	//边界插入到最后一个位置if(p->next=NULL)
}

3.删除

(1).删除p后面的q
(2)p q不为空
(3)三步走 先连p— q-----> x ;再连p<---- q ----x ;释放q
(4)删除最后一个结点: 上面需加条件 q->next!=NULL

//删除p的后继结点q
bool DeleteNextDNode(DNode *p){ 
	DNode *q=p->next;
	if(p==NULL)  
	    return false;
	if(q==NULL)  
	    return false;
	q->next=p->next;  //1
	if(q->next!=NULL){ 删除的那个点->next不为空
		q->next->prior=p;  //2
	}
	free(p);		//3
	return true;
//边界:删除最后一个结点 if(q->next=NULL)
}

4.遍历 & 查找(按值 按位)

4.1 双向链表的后向+ 前向遍历

(1)后向遍历: ==while(p!=NULL) { p=p->next; } ==
(2)前向遍历:(包括头结点): ==while(p!=NULL) { p=p->prior; } ==
前向遍历(不包括头结点): ==while(p->prior!=NULL) { p=p->prior; } ==

遍历代码:
void printfDLinkList(DLinkList &L){
	if(L==NULL)
		return ;
	DLNode *p=L->next;
	while(p!=NULL){
		printf("%d\n",p->data);
		p=p->next;//后向遍历
	}
	return;
}

4.2查找代码

==在遍历基础上修改,时间复杂度O(n) ==
按位查找: while(p!=NULL&&j<i)
按值查找: while(p!=NULL&&p->data!=e)

//查找第i元素返回其值---通过遍历实现---O(n)
bool GetElem(DLinkList L,int i,int &e){
	if(i<0)
		return false;
	if(i==0)
		e=L->data;
		return true;
	int j=1;	//j=1开始的长度
	DLNode *p;
	p=L;
	if(p==NULL)
		return false;
	while(p!=NULL&&j<i)//
	{
		p=p->next;
		j++;
			
	}
	e=p->data;
	return true;
}



//双向链表按值查找---通过遍历实现---O(n)
int DLocateElem(DLinkList L,int e){
	int j=1;
	DLNode *p;
	p=L->next;
	while(p!=NULL&&p->data!=e){//
		p=p->next;
				
		j++;
		printf("%d ",j);
	}
	if(p==NULL)
		return 0;
	return (j);
}

5.双向链表完整代码:

#include "stdafx.h"
#include<stdio.h>
#include<stdlib.h>

//双向链表的类型定义
typedef struct DLNode{
	int data;
	struct DLNode *prior,*next;
}DLNode,*DLinkList;


//双向链表的初始化
bool InitDLinkList(DLinkList &L){
	L=(DLNode*)malloc(sizeof(DLNode));	//分配一个头结点
	if(L==NULL)
		return false;		//内存分配失败
	L->prior=NULL;			//为空
	L->next=NULL;			//为空
	return true;
}

//头插法建立双向链表
DLinkList DList_HeadInsert(DLinkList &L){
	int x;
	L=(DLNode*)malloc(sizeof(DLNode));
	if(L==NULL)
		return false;
	L->next=NULL;
	L->prior=NULL;
	scanf("%d",&x);
	while(x!=9999){
		DLNode *s=(DLNode*)malloc(sizeof(DLNode));
		if(s==NULL)
			return false;
		s->data=x;
		s->next=L->next;
		if(L->next!=NULL)
			L->next->prior=s;
		s->prior=L;
		L->next=s;
		scanf("%d",&x);
	}
	return L;
}



//尾插法建立双向链表
DLinkList DList_TailInsert(DLinkList &L){
	int x;
	L=(DLNode*)malloc(sizeof(DLNode));
	L->next=NULL;
	L->prior=NULL;
	scanf("%d",&x);
	DLNode *p;
	p=L;
	while(x!=9999){
		DLNode *s=(DLNode*)malloc(sizeof(DLNode));
		s->data=x;
		p->next=s;
		s->prior=p;
		p=s;
		scanf("%d",&x);
	}
	p->next=NULL;
	return L;
}





//双链表的销毁
void DestoryDList(DLinkList &L)
{
    DLNode *p,*q;
    p=L;
    q=p->next;
    while(q!=NULL){
       	free(p);
        p=q;
        q=p->next;
    }
    free(p);  //释放头结点
}



//双向链表的清空
bool ClearDLinkList(DLinkList &L){
	if(L==NULL)
		return  false;
	DLNode *p;
	p=L->next;
	while(p!=NULL){
		L=p->next;
		if(p->next!=NULL)
			p->next->prior=L;
		free(p);
		p=L->next;
	}
	L->next=NULL;
	return true;
}



//判断带头结点的双链表是否为空
bool Empty(DLinkList L){
    if(L->next==NULL)
        return true;
    else
        return false;
}


//求双向链表的长度
int DLinkListLen(DLinkList L){
	if(L==NULL)
		return false;
	int j=0;
	DLNode *p;
	p=L;
	while(p->next!=NULL){
		p=p->next;
		j++;

	}
	return (j);
}



//查找第i元素返回其值---通过遍历实现---O(n)
bool GetElem(DLinkList L,int i,int &e){
	if(i<0)
		return false;
	if(i==0)
		e=L->data;
		return true;
	int j=1;	//j=1开始的长度
	DLNode *p;
	p=L;
	if(p==NULL)
		return false;
	while(p!=NULL&&j<i)//
	{
		p=p->next;
		j++;
			
	}
	e=p->data;
	return true;
}



//双向链表按值查找---通过遍历实现---O(n)
int DLocateElem(DLinkList L,int e){
	int j=1;
	DLNode *p;
	p=L->next;
	while(p!=NULL&&p->data!=e){//
		p=p->next;
				
		j++;
		printf("%d ",j);
	}
	if(p==NULL)
		return 0;
	return (j);
}



//双向链表的遍历(打印) 后向遍历 前向遍历
/*后向遍历:while(p!=NULL){	p=p->next; } 
前向遍历:while(p!=NULL){	p=p->prior; }
前向遍历(不包括头结点):while(p->prior!=NULL) {p=p->prior; }

  */
void printfDLinkList(DLinkList &L){
	if(L==NULL)
		return ;
	DLNode *p=L->next;
	while(p!=NULL){
		printf("%d\n",p->data);
		p=p->next;//后向遍历
	}
	return;
}



//p结点后插入s结点
bool InsertNextNode(DLNode *p,DLNode *s){
	if(p==NULL||s==NULL)		//参数非法
		return false;
	s->next=p->next;  //1
	if(p->next!=NULL)	//插入的那个点->next不为空		
		p->next->prior=s;//2
	s->prior=p;      //3
	p->next=s;      //4
	return true;
	//先写后两个箭头
	//边界插入到最后一个位置if(p->next=NULL)
}


//删除p的后继结点q
bool DeleteNextDNode(DLNode *p){ 
	DLNode *q=p->next;
	if(p==NULL)   return false;
	if(q==NULL)   return false;
	q->next=p->next;  //1
	if(q->next!=NULL){ 删除的那个点->next不为空
		q->next->prior=p;  //2
	}
	free(p);		//3
	return true;
//边界:删除最后一个结点 if(q->next=NULL)
}


void main(){
	DLinkList L,s;
	InitDLinkList(L);
	DList_TailInsert(L);
	int a= DLinkListLen(L);
	printf("双向链表的长度为=%d\n",a);
	printfDLinkList(L);

	 printf("位序为:%d\n",DLocateElem(L,5));
	 int e;
	 if(GetElem(L,2,e)==1)
		printf("yes\n");
	 else 
		 printf("no found");

}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值