Day_19,链表的原理及双向链表实现

链表的原理: 链表其中的各个对象按线性顺序排列,与数组不同的是,数组的线性顺序是由数组下表决定的,链表的顺序是由各个对象里的指针决定的。
**双向链表:**双向链表的每个元素都是一个对象,每个对象都有两个指针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.如果有改进方法或者上述算法有误!十分欢迎私信,三人行必有我师!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值