数据结构和算法—双向链表

双向循环链表

初始化
指针域置为空(NULL) 数据域可用可不用

前插法
插入节点插在头节点之后 为前插法

插入节点的next = 头节点的next
插入节点的prev = 头节点
头节点的next = 插入节点

判断是否存在下一个节点
如果 头节点的next != NULL 说明存在, 就需要把下一个节点的prev指向插入节点
如果还是不懂, 可以画图理解一下

尾插法
插入节点插在最后一个节点之后 为尾插法

找到最后一个节点

插入节点的next = NULL
插入节点的prev = 最后一个节点
最后一个节点的next = 插入节点

任意位置插入
找到要插入的位置 把插入节点插在该位置之前, 插在该位置之后也可以(不过需要判断该位置是否存在下一个节点, 存在就把下一个节点的prev 指向插入节点
我这里就插在该位置之前吧

插入节点的next = 该位置的节点
插入节点的prev = 该位置节点的prev节点
该位置节点的prev节点的next = 插入节点
该位置的prev = 插入节点

其他操作类似,如有不懂,可画图理解

代码实现

注:实现了部分代码,而且没有测试代码

#include <iostream>
#include <Windows.h>
#include <stdio.h>

//双向链表的定义
typedef int NodeType;

typedef struct _DLinkList {
	NodeType date;
	struct _DLinkList* next;
	struct _DLinkList* prev;
}DLinkList, DLinkNode;

//双向链表的初始化
bool initDLink(DLinkList* &head) {
	head = new DLinkList;
	if(!head) return false;

	head->date = -1;
	head->next = head->prev = NULL;
	return true;
}

//前插法
bool insertFront(DLinkList* &head, NodeType& e) {
	if(!head) return false;

	DLinkNode* p = new DLinkNode;
	if(!p) return false;

	p->date = e;
	p->next = head->next;
	p->prev = head;
	head->next = p;

	if(head->next) head->next->prev = p;
	return true;
}

//尾插法
bool insertBack(DLinkList* &head, NodeType& e) {
	if(!head) return false;
	
	DLinkNode* last = head;
	DLinkNode* p = NULL;

	while(last->next) {
		last = last->next;	
	}

	p = new DLinkNode;
	if(!p) return false;
	p->date = e;

	p->next = last->next;
	p->prev = last;
	last->next = p;
	return true;
}

// 任意位置插入
bool insertSite(DLinkList* &head, NodeType& e, const int i){
	if(!head) return false;
	if(i<1) return false;

	DLinkNode* p = head;
	DLinkNode* s = NULL;
	
	int count = 0;
	while(p && count < i) {
		p = p->next;
		count++;
	}

	if(!p) return false;
	
	s = new DLinkNode;
	if(!s) return false;

	s->date = e;
	s->next = p;
	s->prev = p->prev;
	p->prev->next = s;
	p->prev = s;

	return true;
}

//遍历
void DLPrint(DLinkList* head) {
	if(!head) return;

	while(head->next) {
		printf("%d  ", head->next->date);
		head = head->next;
	}

	printf("\n");
	
	printf("逆序打印");
	while(head) {
		printf(" %d  ", head->date);
		head = head->prev;
	}

	printf("\n");
}

//双向链表删除节点
bool DLinkDelete(DLinkList* &head, const int i) {
	if(!head || !head->next) return false;
	if(i < 1) return false;
	
	DLinkList* p = head->next;
	int count = 1;
	
	while(p && count < i) {
		p = p->next;
		count++;
	}
	
	if(!p) return false;
	
	p->prev->next = p->next;
	
	//判断删除节点, 是否存在下一个节点, 有就执行, 没有过滤
	if(p->next) p->next->prev = p->prev;

	return true;
}

//双向链表的销毁
bool DLinkDestroy(DLinkList* &head) {
	if(!head) return false;

	DLinkNode* p = head;
	while(p) {
		head = p->next;
		delete p;
		p = head;
	}

	head = NULL;
	return true;
}
发布了18 篇原创文章 · 获赞 2 · 访问量 228

猜你喜欢

转载自blog.csdn.net/weixin_44238530/article/details/102630428