双链表的基本操作代码实例

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>

typedef int EleType;
typedef struct DNode {//双链表就是两个节点互相指向
	EleType data;//数据域
	struct DNode* prior;//前驱指针
	struct DNode* next;//后继指针
}DNode,*DLinkList;//双链表组成是 prior data next 这个顺序

//双链表头插法
DLinkList DList_head_insert(DLinkList& DL) {
	DNode* s; int x;
	DL = (DLinkList)malloc(sizeof(DNode));//带头节点的链表
	DL->next = NULL;
	DL->prior = NULL;
	scanf("%d", &x);
	//3 4 5 6 7 8 9999
	while (x != 9999) {
		s = (DLinkList)malloc(sizeof(DNode));
		s->data= x;//申请空间存入数值
		s->next = DL->next;
		if (DL->next != NULL) {//插入第一个节点时,不需要这一步操作
			DL->next->prior = s;//第一节点时,DL->next->prior没有下一个的prior,指向为空,自然也无法将与s相连接
		}
		s->prior = DL;//prior是一个从后往前链接的指针
		DL->next = s;//这一步一定放在最后面,否则DL的后继节点的指针就会丢失掉,导致插入失败
		scanf("%d", &x);
	}
	return DL;
}

//双链表尾插法
DLinkList DList_tail_insert(DLinkList& DL) {
	int x;
	DL = (DLinkList)malloc(sizeof(DNode));
	DNode* s; 
	DNode*r = DL;//r代表尾指针
	DL->prior = NULL;
	// 3 4 5 6 7 9999
	scanf("%d", &x);
	while (x != 9999) {
		s = (DNode*)malloc(sizeof(DNode));
		s->data = x;

		r->next = s;
		s->prior = r;//prior是一个从后往前链接的指针   (与单链表的尾插法相比,就多了这一步)   
		r = s;//r是尾指针一定是指向新的表尾节点
		scanf("%d", &x);
	}
	r->next = NULL;//尾节点的next指针赋值为NULL
	return DL;
}

//按序号获取节点指针地址
DLinkList GetElem(DLinkList DL,int index) {
	DLinkList p = DL->next;
	int j = 1;
	if (index == 0) {
		return DL;
	}
	if (index < 1) {
		return NULL;
	}

	while (p&& j < index) {
		p= p->next;
		j++;
	}
	return p;
}

//在双链表插入新节点
bool DList_front_insert(DLinkList DL, int index,EleType e) {
	DLinkList p = GetElem(DL, index-1);
	DLinkList s = (DLinkList)malloc(sizeof(DNode));
	if (p==NULL ) {
		return false;
	}
	s->data = e;

	s->next = p->next;//第一步都是插入节点先链接头部节点后面的节点
	p->next->prior = s;//相比单链表的插入主要就是多了pior的链接,将插入节点后面的节点的prior指向s
	s->prior = p;//将s的prior指向插入节点前的位置
	p->next = s;//与第一步相呼应,与插入节点前的节点相链接
	return true;
}

//双链表删除节点
bool DList_Dlete(DLinkList DL, int index) {
	DLinkList p = GetElem(DL,index - 1);
	if (p == NULL) {
		return false;
	}
	DLinkList q;
	q = p->next;
	if (q == NULL) {//删除元素不存在
		return false;
	}
	p->next = q->next;//断链
	if (q->next != NULL) {//判断是否有下一个节点,否则只需断链即可,无需prior回指
		q->next->prior = p;
	}
	free(q);
	return true;
}
//输出双链表
void DListPrint(DLinkList DL) {
	DL = DL->next;
	while (DL!=NULL) {
		printf("%-3d", DL->data);
		DL = DL->next;
	}
	printf("\n");
}






int main() {
	DLinkList DL=NULL;
	DLinkList search;
	//DList_head_insert(DL);

	DList_tail_insert(DL);

	search=GetElem(DL, 2);
	printf("%d\n", search->data);

	bool ret;
	ret = DList_front_insert(DL, 1,66);
	if (ret) {
		printf("Insert orperate sucessful\n");
	}
	else {
		printf("GG\n");
	}
    
	ret = DList_Dlete(DL, 4);
	if (ret) {
		printf("Delete orperate sucessful\n");
	}
	else {
		printf("GG\n");
	}
	DListPrint(DL);
	return 0;
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值