C++数据数据结构算法 学习笔记(6) - 双链表的算法实现
单链表中每个结点除了存储自身数据之后,还存储了下一个结点的地址,因此可以轻松访问 下一个结点,以及后面的后继结点,但是如果想访问前面的结点就不行了,再也回不去了。
例如删除结点 p 时,要先找到它的前一个结点 q,然后才能删掉 p 结点,单向链表只能往 后走,不能向前走。如果需要向前走,怎么办呢?
可以在单链表的基础上给每个元素附加两个指针域,一个存储前一个元素的地址,一个存储 下一个元素的地址。
这种链表称为双向链表.
结构体的定义为:
typedef struct _DbLinkNode
{
int elem;
_DbLinkNode* next;
_DbLinkNode* prev;
}DbLinkNode,DbLinkList;
双向链表的初始化
代码实现:
bool DbList_Init(DbLinkList*& L)
{
L = new DbLinkNode;
if (!L) return false;
L->next = NULL;
L->prev = NULL;
L->data = -1;
return true;
}
双向链表增加元素(前插法)
代码实现:
bool DbListInsert_front(DbLinkList*& L, DbLinkList* 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;
//}
//Optimize the code
if (L->next) 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 DbLinkList_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 << "The Node is not exist" << endl;
return false;
}
cout << "P: " << p << endl;
s = new DbLinkNode;
s->data = e;
s->next = p;
s->prev = p->prev;
p->prev->next = s;
p -> prev = s;
return true;
}
双向链表的遍历(打印)
代码实现:
void DbLink_Print(DbLinkList*& L)
{
DbLinkNode* p = NULL;
if (!L)
{
cout << "the List is NULL" << endl;
return;
}
p = L;
while (p->next)
{
cout << p->next->data << "\t";
p = p->next;
}
cout << endl << "Inverse printing" << endl;
while (p)
{
cout << p->data << "\t";
p = p->prev;
}
cout << endl;
}
双向链表获取元素
代码实现:
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 DbLinkList_Delete(DbLinkList*& L, int i)
{
DbLinkList* p;
int index = 0;
if (!L || !L->next)
{
cout << "List is NULL" << 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;
p->next->prev = p->prev;
delete p;
return true;
}
双线链表 销毁链表
代码实现:
void DbLink_Destroy(DbLinkList*& L)
{
DbLinkList* p = L;
cout << "Destroying the list" << endl;
while (p) {
L = L->next;
cout << "Deleting node: " << p->data << endl;
delete p;
p = L;
}
}