链表的原理: 链表其中的各个对象按线性顺序排列,与数组不同的是,数组的线性顺序是由数组下表决定的,链表的顺序是由各个对象里的指针决定的。
**双向链表:**双向链表的每个元素都是一个对象,每个对象都有两个指针pre和next,对象中可以包含零个或多个辅助数据(称作卫星数据);
设x为双向链表里面的元素
1、如果x.pre = NULL,则表示这是链表的第一个元素,即链表头(head)
2、如果x.next = NULL ,则表示这是链表的最后一个元素,即链表尾(tail)
3、表头(head)指向链表的第一个元素,如果head=NULL表示链表为空
可以参照下图对照着看
下面是基于C++实现的双向链表。
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
template<class T>
class DoubleNode
{
public:
DoubleNode *pre;
DoubleNode *next;
int position;//所在链表的位置
T mValue;//该节点的值
DoubleNode(){}
DoubleNode(T value,DoubleNode * pre,DoubleNode *next){
mValue = value;
pre = pre;
next = next;
}
~DoubleNode(){
}
};
template<class T>
class DoubleLink
{
public:
DoubleLink();
~DoubleLink();
int Search(T value);//返回在链表中的位置
DoubleNode<T> *SearchNode(T value);//返回节点
string Insert(int position,T value);//插入到position位置
void PrintAllValue();//打印整个链表
string Delete(int position);//删除position位置的节点
private:
int length;//链表长度
DoubleNode<T> *head;//头节点
string strTrue;//用于返回true的字符串
string strFalse;//用于返回false的字符串
string strNull;//用于返回null的字符串
};
//构造函数
template<class T>
DoubleLink<T>::DoubleLink()
{
head = new DoubleNode<T>();
strTrue = "true";
strFalse = "false";
strNull = "null";
length = 0;
}
//析构函数,删除掉整个链表
template<class T>
DoubleLink<T>::~DoubleLink()
{
DoubleNode<T> *node = head;
while(node != NULL)
{
DoubleNode<T> *temp = node->next;
node = temp->next;
delete temp;
}
}
//搜索对应value的节点的位置
template<class T>
int DoubleLink<T>::Search(T value)
{
DoubleNode<T> *node = head;
while(node!=NULL)
{
if (node->mValue == value)
break;
node = node->next;
}
if(node->mValue == value)
return node->position;
else
return 0;
}
//搜索对应value的节点
template<class T>
DoubleNode<T> *DoubleLink<T>::SearchNode(T value)
{
DoubleNode<T> *node = head;
while(node!=NULL)
{
if (node->mValue == value)
break;
node = node->next;
}
if(node->mValue==value)
return node;
else
return NULL;
}
//插入函数,如果position在当前链表长度范围内,则在对应位置插入,否则直接插入到末尾
//插入方式 A、B、C 插入D到2
//变成A、D、B、C
template<class T>
string DoubleLink<T>::Insert(int position,T value)
{
DoubleNode<T> *node = head;
DoubleNode<T> *addNode = new DoubleNode<T>();
//首个插入的节点,插入链表头
if (length == 0)
{
addNode->mValue = value;
addNode->position = 1;
addNode->pre = NULL;
addNode->next = NULL;
node->pre = addNode;
length = 1;
head = addNode;
return strTrue;
}
//随机插入的节点
//需要考虑最终搜索完node==NULL的情况(表示position超出链表总长)
DoubleNode<T> *pre;//上一个节点
while(node!=NULL)
{
pre = node;
if (node->position==position)
break;
node = node->next;
}
//找不到对应节点,加到链表尾部
if (node==NULL)
{
addNode->mValue = value;
addNode->position = pre->position+1;
addNode->next = NULL;
addNode->pre = pre;
pre->next = addNode;
}
else//插入链表之间
{
pre = node->pre;
if (pre!=NULL) //如果加入的刚好是头节点,pre是NULL
pre->next = addNode;
addNode->mValue = value;
addNode->position = position;
addNode->next = node;
addNode->pre = node->pre;
node->pre = addNode;
}
if (addNode->position == 1)
head = addNode;
while(node!=NULL)
{
node->position += 1;
if (node->next ==NULL)
length = node->position;
node = node->next;
}
return strTrue;
}
template<class T>
void DoubleLink<T>::PrintAllValue()
{
DoubleNode<T> *node = head;
while(node!=NULL)
{
cout<<node->position<<" "<<node->mValue<<endl;
node = node->next;
}
}
template<class T>
string DoubleLink<T>::Delete(int position)
{
DoubleNode<T> *node = head;
while(node!=NULL)
{
if (node->position == position)
{
DoubleNode<T> *temp = node;
DoubleNode<T> *pre = node->pre;
node = node->next;
node->pre = pre;
pre->next = node;
delete temp;
break;
}
node = node->next;
}
while(node!=NULL)
{
node->position -=1;
node = node->next;
}
}
int main()
{
DoubleLink<string> *dLink = new DoubleLink<string>();
dLink->Insert(1,"my");
dLink->Insert(1,"name");
dLink->Insert(1,"is");
dLink->Insert(2,"hong");
dLink->Insert(16,"better");
dLink->PrintAllValue();
cout<<"name position is "<<dLink->Search("name")<<endl;
dLink->Delete(2);
dLink->PrintAllValue();
cout<<"node my position "<<dLink->SearchNode("my")->position<<endl;
return 0;
}
拖更了这么久的算法!总算更新了!
PS.如果有改进方法或者上述算法有误!十分欢迎私信,三人行必有我师!