前言
单链表结点中只有一个指向其后继的指针,使得单链表只能从头结点依次顺序地向后遍历。要访问某个结点的前驱结点(插入,删除操作时),只能从头开始遍历,访问后继结点的时间复杂度为O(1),访问前驱结点的时间复杂度为O(n)。
提示:以下是本篇文章正文内容,下面案例可供参考
一、双向链表是什么?
为了克服单链表的上述缺点,引入了双链表,双链表结点中有两个指针prev和next,分别指向其前驱结点和后继结点。
二、双向链表上的基本操作
1.定义双向链表
代码如下(示例):
typedef struct DoubleLinkList {
int data;
DoubleLinkList* next;
DoubleLinkList* prev;
}DoubleLinkList,DoubleLinkNode;
2.初始化双链表
代码如下(示例):
bool DoubleLinkListInit(DoubleLinkList* &L) {
L = new DoubleLinkNode;
if (!L)return true;
L->next = NULL;
L->prev = NULL;
L->data = -1;
return true;
}
3.前插法创建双链表
代码如下(示例):
bool DoubleLinkListInsertFront(DoubleLinkList*& L, DoubleLinkNode* node) {
if (!L || !node) return false;
if (L->next == NULL) {
node->next = NULL;
node->prev = L;
L->next = node;
}
else {
L->next->prev = node;
node->next = L->next;
node->prev = L;
L->next = node;
}
return true;
}
4.尾插法创建双链表
代码如下(示例):
bool DoubleLinkListInsertBack(DoubleLinkList*& L, DoubleLinkNode* node) {
DoubleLinkNode* last = NULL;
if (!L || !node) return false;
last = L;
while (last->next) last = last->next;
node->next = NULL;
node->prev = last;
last->next = node;
return true;
}
5.双向链表的遍历输出
代码如下(示例):
void DoubleLinkListPrint(DoubleLinkList* &L) {
DoubleLinkNode* p=L;
if (!L) {
cout << "链表为空" << endl;
return;
}
while (p->next) {
cout << p->next->data << " ";
p = p->next;
}
cout << endl << "逆向打印" << endl;
while (p) {
cout << p->data << " ";
p = p->prev;
}
cout << endl;
return;
}
6.双链表的指定位置插入
代码如下(示例):
bool DoubleLinkListInsert(DoubleLinkList* L,int i,int e) {
if (!L || !L->next) return false;
if (i < 1)return false;
int j = 0;
DoubleLinkList* p, * s;
p = L;
while (p && j < i) {
p = p->next;
j++;
}
if (!p || j != i) {
cout << "结点不存在" << i << endl;
return false;
}
s = new DoubleLinkNode;
s->data = e;
s->next = p;
s->prev = p->prev;
p->prev->next = s;
p->prev = s;
return true;
}
7.双链表的按位取值
代码如下(示例):
bool DoubleLinkListGetElem(DoubleLinkList* &L,int i,int& e) {
int index;
DoubleLinkList* p;
if (!L || !L->next) return false;
p = L->next;
index = 1;
while (p || index < i) {
p = p->next;
index++;
}
if (!p || index > i) {
return false;
}
e = p->data;
return true;
}
8.双链表的任意位置删除
代码如下(示例):
bool DoubleLinkListDelete(DoubleLinkList*& L, int i) {
DoubleLinkList* p;
int index = 0;
if (!L || !L->next) {
cout << "双向链表为空!" << endl;
return false;
}
if (i < 1) {
cout << "不能删除头结点!" << endl;
return false;
}
p = L;
while (p && index < i) {
p = p->next;
index++;
}
if (!p)return false;
p->prev->next = p->next;
p->next->prev = p->prev;
delete p;
return true;
}
9.双链表的销毁
代码如下(示例):
void DoubleLinklistDestroy(DoubleLinkList* &L) {
DoubleLinkList* p = L;
cout << "销毁链表" << endl;
while (p) {
L = L->next;
delete p;
p = L;
}
}
三、全部代码(主函数部分比较凌乱)
#include<iostream>
using namespace std;
typedef struct DoubleLinkList {
int data;
DoubleLinkList* next;
DoubleLinkList* prev;
}DoubleLinkList,DoubleLinkNode;
bool DoubleLinkListInit(DoubleLinkList* &L) {
L = new DoubleLinkNode;
if (!L)return true;
L->next = NULL;
L->prev = NULL;
L->data = -1;
return true;
}
bool DoubleLinkListInsertFront(DoubleLinkList*& L, DoubleLinkNode* node) {
if (!L || !node) return false;
if (L->next == NULL) {
node->next = NULL;
node->prev = L;
L->next = node;
}
else {
L->next->prev = node;
node->next = L->next;
node->prev = L;
L->next = node;
}
return true;
}
bool DoubleLinkListInsertBack(DoubleLinkList*& L, DoubleLinkNode* node) {
DoubleLinkNode* last = NULL;
if (!L || !node) return false;
last = L;
while (last->next) last = last->next;
node->next = NULL;
node->prev = last;
last->next = node;
return true;
}
void DoubleLinkListPrint(DoubleLinkList* &L) {
DoubleLinkNode* p=L;
if (!L) {
cout << "链表为空" << endl;
return;
}
while (p->next) {
cout << p->next->data << " ";
p = p->next;
}
cout << endl << "逆向打印" << endl;
while (p) {
cout << p->data << " ";
p = p->prev;
}
cout << endl;
return;
}
bool DoubleLinkListInsert(DoubleLinkList* L,int i,int e) {
if (!L || !L->next) return false;
if (i < 1)return false;
int j = 0;
DoubleLinkList* p, * s;
p = L;
while (p && j < i) {
p = p->next;
j++;
}
if (!p || j != i) {
cout << "结点不存在" << i << endl;
return false;
}
s = new DoubleLinkNode;
s->data = e;
s->next = p;
s->prev = p->prev;
p->prev->next = s;
p->prev = s;
return true;
}
bool DoubleLinkListGetElem(DoubleLinkList* &L,int i,int& e) {
int index;
DoubleLinkList* p;
if (!L || !L->next) return false;
p = L->next;
index = 1;
while (p || index < i) {
p = p->next;
index++;
}
if (!p || index > i) {
return false;
}
e = p->data;
return true;
}
bool DoubleLinkListDelete(DoubleLinkList*& L, int i) {
DoubleLinkList* p;
int index = 0;
if (!L || !L->next) {
cout << "双向链表为空!" << endl;
return false;
}
if (i < 1) {
cout << "不能删除头结点!" << endl;
return false;
}
p = L;
while (p && index < i) {
p = p->next;
index++;
}
if (!p)return false;
p->prev->next = p->next;
p->next->prev = p->prev;
delete p;
return true;
}
void DoubleLinklistDestroy(DoubleLinkList* &L) {
DoubleLinkList* p = L;
cout << "销毁链表" << endl;
while (p) {
L = L->next;
delete p;
p = L;
}
}
int main() {
DoubleLinkList* L;
DoubleLinkList* s;
if (DoubleLinkListInit(L)) {
cout << "初始化链表成功!" << endl;
}
else {
cout << "初始化链表失败!" << endl;
}
int n;
cout << "使用前插法创建双向链表" << endl;
cout << "请输入元素个数:";
cin >> n;
cout << endl << "依次输入" << n << "个元素: ";
while (n > 0) {
s = new DoubleLinkNode;
cin >> s->data;
DoubleLinkListInsertFront(L, s);
n--;
}
DoubleLinkListPrint(L);
cout << "使用尾插法创建双向链表" << endl;
cout << "请输入元素个数:";
cin >> n;
cout << endl << "依次输入" << n << "个元素: ";
while (n > 0) {
s = new DoubleLinkNode;
cin >> s->data;
DoubleLinkListInsertBack(L, s);
n--;
}
DoubleLinkListPrint(L);
for (int j = 0; j < 3; j++) {
int i, x;
cout << "请输入要插入的位置和元素(用空格隔开):";
cin >> i >> x;
if (DoubleLinkListInsert(L, i, x)) {
cout << "插入成功!" << endl;
}
else {
cout << "插入失败!" << endl;
}
DoubleLinkListPrint(L);
}
if (DoubleLinkListDelete(L, 2)) {
cout << "删除链表第2个元素成功" << endl;
}
else
cout << "删除链表第2个元素失败!" << endl;
DoubleLinkListPrint(L);
DoubleLinklistDestroy(L);
return 0;
}
总结
以上就是今天要讲的内容,本文仅仅简单介绍了双向链表的基本操作,如有错误,欢迎大家指针,看完记得点个赞。
|