当前位置:   article > 正文

数据结构之线性表(双链表)_设指针p指向双链表的某一结点,则双链表结构的对称性

设指针p指向双链表的某一结点,则双链表结构的对称性


一、双链表的定义与表示

1.双链表结点结构

在这里插入图片描述

2.双链表结点结构的定义

typedef struct DLNode{
	Elemtype data;     //data中存放结点数据域
	struct DLNode *prior; //指向前驱结点的指针
	struct DLNode *next; //指向后继节点的指针
}DLNode,*DLinkList; //DLinList为指向结构体DLNode的指针类型
  • 1
  • 2
  • 3
  • 4
  • 5

二、双链表

1.双链表结构的对称性

双链表结构的对称性(设指针p指向某一结点)
p->prior->next = p = p->next->prior
在这里插入图片描述
:在双链表的一些操作中(如:求表长,取元素值和查找元素等),如果只涉及到一个方向上的指针,它们的算法与线性表相同。但是,在插入、删除时,则需要同时修改两个方向上的指针。

2.建立双链表

2.1.头插法建表

//头插法建立双链表 
void createListH(DLinkList &L,int n){
	DLinkList s;
	L=(struct DLNode*)malloc(sizeof(struct DLNode)); //创建头结点
	L->next=NULL;  //后指针域设为空
	L->prior=NULL;  //前指针域设为空
	for(int i=0;i<n;i++){
		s=(struct DLNode*)malloc(sizeof(struct DLNode));  //循环建立数据结点
		scanf("%d",&s->data);
		s->next=L->next;   //将s结点插在头结点之后
		if(L->next!=NULL){  //若L中存在数据节点,修改L->next的前驱指针
			L->next->prior=s;
		}
		L->next=s;
		s->prior=L;	
	} 	
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

2.2.尾插法建表

//尾插法建立双链表
void creatListR(DLinkList &L,int n){
	DLinkList r,s;
	L=(struct DLNode*)malloc(sizeof(struct DLNode)); //创建头结点
	L->next=L->prior=NULL; //前后指针域置为空
	r=L;    //r始终指向尾结点,开始时指向头结点
	for(int i=0;i<n;i++){
		s=(struct DLNode*)malloc(sizeof(struct DLNode));  //创建数据结点s
		scanf("%d",&s->data);
		s->next=NULL;
		r->next=s;
		s->prior=r;
		r=s;
	} 	
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

3.插入数据结点

在双链表L中第i个位置上插入数据元素e

//插入数据元素
bool insertList(DLinkList &L,int i,ElemType e){
	DLinkList p,s;
	p=L;  //p指向头结点
	int j=0;    //j初始为0
	while(p->next!=NULL&&j<i-1){   //找到第i-个结点p
		j++;
		p=p->next;
	}
	if(p==NULL||i<=0){    //没有找到或者是参数错误,返回false
		return false;
	}
	else{
		s=(struct DLNode*)malloc(sizeof(struct DLNode));    //创建一个数据结点s
		s->data=e;
		s->next=p->next;
		if(p->next!=NULL){  //若p结点存在后继结点,修改这个后继结点的前驱指针
			p->next->prior=s;
		}
		s->prior=p;
		p->next=s;
		
		return true;	
	}
	
} 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

4.删除数据结点

在双链表中删除第i个结点
:不管是在第i个位置上插入一个结点,还是删除第i 个结点,都要注意,要插入的结点的位置或者是要删除的那个结点是否存在后继结点。在写代码时,这点很容易被忽视。

//删除数据结点
bool delList(DLinkList &L,int i){
	DLinkList p,q,s;
	p=L;
	int j=0;
	while(p->next!=NULL&&j<i-1){  //找到第i-1个结点p
		j++;
		p=p->next;
	}
	if(p==NULL||i<=0){
		return false;
	}
	else{
		q=p->next;   //q指向第i个结点,也就是要删除的结点
		if(q==NULL){
			return false;
		}
		p->next=q->next;
		if(q->next!=NULL){ //若q结点存在后继结点,修改这个后继结点的前驱指针
			q->next->prior=p;
		}
		free(q);
		return true;	
	}
} 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

5.输出双链表

//输出双链表
void printList(DLinkList L){
	DLinkList p;
	p=L->next;
	while(p){
		printf("%4d",p->data);
		p=p->next;
	}
	printf("\n");
} 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

三、循环双链表

  1. 和单链表的循环表类似,双链表也有循环表
  2. 让头结点的前驱指针指向链表的最后一个结点
  3. 让最后一个结点的后继指针指向头结点
    在这里插入图片描述
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号