数据结构与算法 双向链表
双向链表
对于双向链表来说,它无非就是在单链表的基础上,在链表中多增加了一个指针域,用来存储上一个节点的地址。 单链表没有上一个节点的地址,所以无法访问它,只能访问它下一个节点,而双向链表因其比单链表多一个指针域用来存储上一个节点的地址,所以可以访问,这就是双向链表。
1.初始化双向链表
双向链表初始化只是在单链表的基础上多增加了一个指针域,所以变化不大,初始化这个指针就可以了。
typedef struct _DoubleLinkNode
{
int data
;
struct _DoubleLinkNode
* next
;
struct _DoubleLinkNode
* prev
;
}DLinkNode
, DLinkList
;
bool DInitList(DLinkList
*& L
) {
L
= new DLinkNode
;
if (!L
) {
cout
<< "初始化链表失败!" << endl
;
return false;
}
L
->next
= NULL;
L
->prev
= NULL;
L
->data
= -1;
cout
<< "初始化链表成功!" << endl
;
return true;
}
2.前插法
(在不是空链表的情况下L为头节点)L->next为头节点的下一个节点的地址,L->next->prev为头(本)节点的地址,在单链表的基础上,多了一个逆指向。
bool DbListInsert_front(DbLinkList
* &L
, DbLinkNode
*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;
}
3.尾插法
与单链表大体相同
bool DbListInsert_back(DbLinkList
* &L
, DbLinkNode
*node
){
DbLinkNode
*last
= NULL;
if(!L
|| !node
) return false;
last
= L
;
while(last
->next
) last
= last
->next
;
node
->next
= NULL;
last
->next
= node
;
node
->prev
= last
;
return true;
}
4.任意位置插入
bool DbLink_Insert(DbLinkList
* &L
, int i
, int &e
){
if(!L
||!L
->next
) return false;
if(i
<1) return false;
int j
=0;
DbLinkList
*p
, *s
;
p
= L
;
while(p
&& j
<i
){
p
= p
->next
;
j
++;
}
if(!p
|| j
!=i
){
cout
<<"不存在节点:"<<i
<<endl
;
return false;
}
s
= new DbLinkNode
;
s
->data
= e
;
s
->next
= p
;
s
->prev
= p
->prev
;
p
->prev
->next
= s
;
p
->prev
= s
;
return true;
}
5.双向链表按位置取值
bool DbLink_GetElem(DbLinkList
*& L
, int i
, int& e
) {
int index
;
DbLinkList
*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;
}
6.任意位置删除
bool DbLink_Delete(DbLinkList
*& L
, int i
) {
DbLinkList
* p
;
int index
= 0;
if (!L
|| !L
->next
) {
cout
<< "双向链表为空!" << endl
;
return false;
}
if (i
< 1) return false;
p
= L
;
while (p
&& index
< i
) {
p
= p
->next
;
index
++;
}
if (!p
) {
return false;
}
p
->prev
->next
= p
->next
;
if (p
->next
) {
p
->next
->prev
= p
->prev
;
}
delete p
;
return true;
}
7.销毁链表
void DbLink_Destroy(DbLinkList
*& L
) {
DbLinkList
*p
= L
;
while(p
){
L
=L
->next
;
cout
<<"删除元素: "<<p
->data
<<endl
;
delete p
;
p
= L
;
}
cout
<< "链表已销毁!" << endl
;
}
8.打印链表
void DbLink_Print(DbLinkList
* &L
){
DbLinkNode
*p
= NULL;
if(!L
){
cout
<<"链表为空."<<endl
;
return ;
}
p
= L
;
while(p
->next
){
cout
<<p
->next
->data
<<"\t";
p
= p
->next
;
}
cout
<<endl
<<"逆向打印"<<endl
;
while(p
){
cout
<<p
->data
<<"\t";
p
= p
->prev
;
}
cout
<<endl
;
}
完整代码
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std
;
typedef struct _DoubleLinkNode
{
int data
;
struct _DoubleLinkNode
* next
;
struct _DoubleLinkNode
* prev
;
}DbLinkNode
, DbLinkList
;
bool DbInitList(DbLinkList
*& L
) {
L
= new DbLinkNode
;
if (!L
) {
cout
<< "初始化链表失败!" << endl
;
return false;
}
L
->next
= NULL;
L
->prev
= NULL;
L
->data
= -1;
cout
<< "初始化链表成功!" << endl
;
return true;
}
bool DbListInsert_front(DbLinkList
* &L
, DbLinkNode
*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 DbListInsert_back(DbLinkList
* &L
, DbLinkNode
*node
){
DbLinkNode
*last
= NULL;
if(!L
|| !node
) return false;
last
= L
;
while(last
->next
) last
= last
->next
;
node
->next
= NULL;
last
->next
= node
;
node
->prev
= last
;
return true;
}
bool DbLink_Insert(DbLinkList
* &L
, int i
, int &e
){
if(!L
||!L
->next
) return false;
if(i
<1) return false;
int j
=0;
DbLinkList
*p
, *s
;
p
= L
;
while(p
&& j
<i
){
p
= p
->next
;
j
++;
}
if(!p
|| j
!=i
){
cout
<<"不存在节点:"<<i
<<endl
;
return false;
}
s
= new DbLinkNode
;
s
->data
= e
;
s
->next
= p
;
s
->prev
= p
->prev
;
p
->prev
->next
= s
;
p
->prev
= s
;
return true;
}
bool DbLink_GetElem(DbLinkList
*& L
, int i
, int& e
) {
int index
;
DbLinkList
*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 DbLink_Delete(DbLinkList
*& L
, int i
) {
DbLinkList
* p
;
int index
= 0;
if (!L
|| !L
->next
) {
cout
<< "双向链表为空!" << endl
;
return false;
}
if (i
< 1) return false;
p
= L
;
while (p
&& index
< i
) {
p
= p
->next
;
index
++;
}
if (!p
) {
return false;
}
p
->prev
->next
= p
->next
;
if (p
->next
) {
p
->next
->prev
= p
->prev
;
}
delete p
;
return true;
}
void DbLink_Destroy(DbLinkList
*& L
) {
DbLinkList
*p
= L
;
while(p
){
L
=L
->next
;
cout
<<"删除元素: "<<p
->data
<<endl
;
delete p
;
p
= L
;
}
cout
<< "链表已销毁!" << endl
;
}
void DbLink_Print(DbLinkList
* &L
){
DbLinkNode
*p
= NULL;
if(!L
){
cout
<<"链表为空."<<endl
;
return ;
}
p
= L
;
while(p
->next
){
cout
<<p
->next
->data
<<"\t";
p
= p
->next
;
}
cout
<<endl
<<"逆向打印"<<endl
;
while(p
){
cout
<<p
->data
<<"\t";
p
= p
->prev
;
}
cout
<<endl
;
}
int main(void) {
DbLinkList
* L
= NULL;
DbLinkNode
* s
= NULL;
DbInitList(L
);
int n
;
cout
<<"前插法创建双向链表"<<endl
;
std
::cout
<<"请输入元素个数 n:";
cin
>>n
;
cout
<< "\n 请依次输入 n 个元素:" << endl
;
while (n
> 0) {
s
= new DbLinkNode
;
cin
>>s
->data
;
DbListInsert_front(L
, s
);
n
--;
}
cout
<<"尾插法创建双向链表"<<endl
;
std
::cout
<<"请输入元素个数 n:";
cin
>>n
;
cout
<<"\n 请依次输入 n 个元素:" <<endl
;
while(n
>0){
s
= new DbLinkNode
;
cin
>>s
->data
;
DbListInsert_back(L
, s
);
n
--;
}
DbLink_Print(L
);
for(int j
=0; j
<3; j
++){
int i
, x
;
cout
<< "请输入插入的位置和元素(用空格隔开):";
cin
>> i
;
cin
>> x
;
if(DbLink_Insert(L
, i
, x
)){
cout
<< "插入成功.\n\n";
}else{
cout
<< "插入失败!\n\n";
}DbLink_Print(L
);
}
int element
= 0;
if(DbLink_GetElem(L
, 2, element
)){
cout
<<"获取第二个元素成功, 值:"<<element
<<endl
;
}else {
cout
<< "获取第二个元素失败!" << endl
;
}
if(DbLink_Delete(L
, 2)){
cout
<<"删除第 2 个元素成功!"<<endl
;
DbLink_Print(L
);
}else {
cout
<<"删除第 2 个元素失败!"<<endl
;
}if(DbLink_Delete(L
, 1)){
cout
<<"删除第 1 个元素成功!"<<endl
;
DbLink_Print(L
);
}else {
cout
<<"删除第 1 个元素失败!"<<endl
;
}
DbLink_Destroy(L
);
system("pause");
return 0;
}