考研数据结构之线性表(1.3)——双链表的操作(C表示)

代码如下:

#include <stdio.h>
#include <stdlib.h>
// 声明双链表的结构体
struct DLNode {
	int data;
	struct DLNode *prior;
	struct DLNode *next;
};

/* 创建一个双链表(使用尾插法) */
/* *&L指的是要创建的单链表;a[]指的是要批量添加的整数数组;n指的是数组长度 */
void createDlistR(DLNode *&L,int a[],int n) {
	DLNode *temp,*node;
	L=(DLNode *)malloc(sizeof(DLNode));
	L->prior=NULL;
	L->next=NULL;
	temp=L;
	for(int i=0; i<n; i++) {
		node=(DLNode *)malloc(sizeof(DLNode));
		node->data=a[i];
		/* 下面3句将node插入到L的尾部,并且temp指向node,node->prior=temp;这一句是和建立单链表不同的地方 */
		temp->next=node;
		node->prior=temp;
		temp=node;
	}
	temp->next=NULL;
}

/* 打印双链表 */
/* *list指的是要被打印的双链表 */
void printList(DLNode *list) {
	printf("\n");
	while(list->next!=NULL) {
		printf("%d\t",list->next->data);
		list=list->next;
	}
	printf("\n");
}

/* 求双链表的表长的算法 */
/* *list指的是双链表 */
int length(DLNode *list) {
	DLNode *temp=list->next;// 临时指针变量
	int i=0; // 计数器,用来统计表长,初始长度为0
	while(temp!=NULL) { // 循环条件,当单链表中结点不为NULL
		temp=temp->next; // 指向下一个结点
		i++; // 计数器加1
	}
	return i;
}

/* 通过值查找结点的算法 */
/* *list指的是双链表;x指的是要查找的值 */
DLNode * findNode(DLNode *list,int x) {
	// 在双链表中查找第一个值为x的结点,从第一个结点开始,边扫描边比较,若找到这样的则返回结点指针,否则返回NULL
	DLNode *temp=list->next;// 获取双链表的第一个结点(不是头结点)
	while(temp!=NULL) { // 循环遍历
		if(temp->data==x) { // 查找到值后跳出while循环
			break;
		}
		temp=temp->next; // 到下一个结点
	}
	return temp; // 返回查找到的结点指针
}

/* 通过序号(不是下标)查找结点的算法 */
/* *list指的是双链表;p指的是要查找的序号 */
DLNode * find(DLNode *list,int p) {
	DLNode *temp;
	temp=list->next;
	int i=1;
	while(temp!=NULL&&i<p) {
		i++;
		temp=temp->next;
	}
	if(i==p) {
		return temp;
	} else {
		return NULL;
	}
}

/* 在双链表中的指定位置插入一个新结点 */
/* *&list指的是要被操作的双链表;pos指的是要插入的序号位置(不是下标);data指的是结点数据 */
void insert(DLNode *&list,int pos,int data) {
	DLNode *priorNode,*node,*temp;
	temp=list->next;
	/* 分情况讨论:(1)插入位置是首位;(2)插入位置不是首位 */
	/* (1)插入位置是首位 */
	if(pos==1) {
		node=(DLNode *)malloc(sizeof(DLNode)); // 创建新结点
		node->data=data; // 设置新结点的数据
		/* 双链表插入结点的核心代码start */
		node->next=temp;
		temp->prior=node;
		list->next=node;
		node->prior=list;
		/* 双链表插入结点的核心代码end */
		return;
	}
	priorNode=find(list,pos-1); // 获取要插入位置的前一个结点指针
	if(priorNode==NULL) {
		printf("第%d个结点不存在!",pos-1);
	} else if(priorNode->next==NULL) {
		printf("第%d个结点不存在!",pos);
	} else {
		node=(DLNode *)malloc(sizeof(DLNode));
		node->data=data;
		node->next=priorNode->next;
		priorNode->next->prior=node;
		node->prior=priorNode;
		priorNode->next=node;
	}
}

/* 删除双链表中指定序号位置(不是下标)的结点元素 */
/* *&list指的是要进行操作的双链表;pos指的是要删除的序号位置 */
void deleteNode(DLNode *&list,int pos) {
	DLNode *temp,*priorNode,*tempDelNode;
	temp=list->next;
	/* 分情况讨论:(1)删除序号位置是首位 ;(2)删除序号位置是首位 */
	/* (1)删除序号位置是首位 ; */
	if(pos==1) {
		/* 双链表删除结点的核心代码start */
		tempDelNode=temp;
		tempDelNode->next->prior=list;
		list->next=tempDelNode->next;
		free(tempDelNode);
		/* 双链表删除结点的核心代码end */
		return;
	}
	/* (2)删除序号位置是首位 */
	priorNode=find(list,pos-1); // 获取要被删除结点的前一个结点的指针
	if(priorNode==NULL) {
		printf("第%d个结点不存在!",pos-1);
	} else if(priorNode->next==NULL) {
		printf("第%d个结点不存在!",pos);
	} else {
		tempDelNode=priorNode->next;
		tempDelNode->next->prior=priorNode;
		priorNode->next=tempDelNode->next;
		free(tempDelNode);
	}

}

int main() {
	DLNode *list,*t1,*t2;

	/* [0.]创建初始测试双链表 */
	int a[]= {1,3,5,7,9}; // 要批量插入到双链表中的结点元素
	createDlistR(list,a,5); // 创建一个双链表(带头结点),其中有些元素

	/* [1.]打印双链表 */
	printList(list);

	/* [2.]双链表的长度 */
	printf("\n%d\n",length(list)); // 打印双链表的长度

	/* [3.]查找结点 */
	t1=findNode(list,7); // 在双链表中查找data值为7的结点
	printf("\n%d\n",t1->data); // 打印查找到结点的data值

	/* [4.]按序号查找结点 */
	t2=find(list,3); // 在双链表中查找序号位置为3的结点
	printf("\n%d\n",t2->data); // 打印查找到的结点的data

	/* [5.]插入新结点 */
	insert(list,1,99); // 在序号位置为1的地方插入一个data值为99的新结点
	printList(list); // 打印插入后的双链表

	/* [6.]删除结点 */
	deleteNode(list,1); // 删除双链表中序号位置为1的结点
	printList(list); // 打印删除后的双链表

	return 0;
}

代码运行结果如下:

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值