雙向鏈表只是在單向鏈表的基礎上增加了一條前向鏈,其中的很多處理方法都是相似的。比如
求鏈表長、尋找某一節點等。所有相似的部分就不一一實現了。有興趣可以參考前面的博文。
以下我實現的雙向鏈表(VC6下實現)。錯誤之處還請指正。
1、代碼組織
2、dll.h雙鏈表及節點的說明
#ifndef _DLL_H_
#define _DLL_H_
#define dataType int
#define endOfData 0
class node
{
public:
dataType data; //節點數據
node *next; //後向指針(離尾節點近)
node *pre; //前向指針(離head近)
};
class dll
{
public:
dll();
~dll();
void create(); //構造雙向鏈表
void print(); //打印鏈表
bool insert(int pos,dataType num); //在位置pos插入num節點.插入完成返回true,否則返回false
void del(dataType num); //刪除鏈表中所有的num節點
private:
int getLength(); //獲取鏈表包含的節點數目
node *head; //鏈表頭指針
};
#endif
3、dll.cpp雙鏈表類函數
#include <iostream>
#include "dll.h"
using namespace std;
dll::dll()
{
head = NULL;
}
dll::~dll()
{
node *ptrNode = head;
node *ptrNodeTmp = NULL;
while(ptrNode != NULL)
{
ptrNodeTmp =ptrNode->next;
delete ptrNode;
ptrNode = ptrNodeTmp;
}
}
void dll::create()
{
//第一個節點
node *ptrNode = new node;
ptrNode->pre = NULL;
ptrNode->data = endOfData;
head = ptrNode;
bool firstNode = true; //是否是第一個節點
dataType num = endOfData;
while(1)
{
cout<<"請輸入一個節點數據: ";
cin>>num;
if(num == endOfData)
{
ptrNode->next = NULL;
break;
}
if(firstNode == false) //以後的節點都需要new node
{
node *ptrNodeTmp = new node;
ptrNodeTmp->data = num;
ptrNode->next = ptrNodeTmp;
ptrNodeTmp->pre = ptrNode;
ptrNode = ptrNodeTmp;
}
if(firstNode == true) //第一個不需要new node
{
ptrNode->data = num;
firstNode = false;
}
}
if(head->data == endOfData) //鏈表中並無數據,需要將第一個節點刪除
{
delete head;
head = NULL;
}
}
void dll::print()
{
node *ptrNode = head;
while(ptrNode != NULL)
{
cout<<ptrNode->data<<" ";
ptrNode = ptrNode->next;
}
cout<<endl;
}
int dll::getLength()
{
node *ptrNode = head;
int num = 0;
while(ptrNode != NULL)
{
num++;
ptrNode = ptrNode->next;
}
return num;
}
bool dll::insert(int pos,dataType num)
{
if(pos < 0 || pos >= getLength()) //插入的pos不正確(0-getLength()-1)
{
return false;
}
//找到待插入pos的指針和後一個指針
node *ptrNodeAhead = head;
node *ptrNodeFellow = NULL;
int count = 0;
while(1)
{
if(count++ == pos) break;
ptrNodeFellow = ptrNodeAhead;
ptrNodeAhead = ptrNodeAhead->next;
}
node *ptr = new node;
ptr->data = num;
ptr->pre = ptrNodeFellow;
ptr->next = ptrNodeAhead;
if(ptrNodeFellow != NULL) //不是插入頭節點
{
ptrNodeFellow->next = ptr;
}
else //插入頭節點,head要改變
{
head = ptr;
}
ptrNodeAhead->pre = ptr;
return true;
}
void dll::del(dataType num)
{
node *ptrNodeAhead = head; //ptrNodeAhead指向待刪除的節點
node *ptrNodeFellow = NULL; //ptrNodeFellow指向待刪除節點的前一節點(離head近的節點)
while(ptrNodeAhead != NULL)
{
while(ptrNodeAhead->data != num && ptrNodeAhead->next != NULL) //找到num節點或是搜索結束
{
ptrNodeFellow = ptrNodeAhead;
ptrNodeAhead = ptrNodeAhead->next;
}
if(ptrNodeAhead->data == num) //找到num節點
{
node *ptrNode = ptrNodeAhead->next;
if(ptrNodeAhead != head) //不是刪除頭節點
{
ptrNodeFellow->next = ptrNode;
}
else //刪除頭結點要注意head指針的賦值
{
head = ptrNodeAhead->next;
}
if(ptrNodeAhead->next != NULL) //不是刪除尾節點
{
ptrNode->pre = ptrNodeFellow;
}
delete ptrNodeAhead; //釋放num節點
ptrNodeAhead = ptrNode;
}
else //搜索結束
{
ptrNodeAhead = NULL;
}
}
}
4、mian.cpp測試文件
#include <iostream>
#include "dll.h"
using namespace std;
int main()
{
dll exp;
//構建鏈表並打印
exp.create();
exp.print();
//在位置2插入99999並打印
exp.insert(2,99999);
exp.print();
//刪除位置2的節點並打印
exp.del(2);
exp.print();
return 0;
}