C/C++學習(九)循環雙鏈表的操作之創建,插入、刪除

雙向鏈表

循環單鏈表的出現,雖然能夠實現從任一結點出發沿着鏈能找到其前驅結點,但時間耗費是On)。如果希望從表中快速確定某一個結點的前驅,另一個解決方法就是在單鏈表的每個結點裏再增加一個指向其前驅的指針域prior。這樣形成的鏈表中就有兩條方向不同的鏈,我們可稱之爲雙(向)鏈表(Double Linked List)。雙鏈表的結構定義如下:

//建立一個線性雙向鏈表的存儲結構

    typedef struct DuLnode
   {
        T data;
        struct DuLnode *prior;//建立一個前趨指針域
        struct DuLnode *next;//建立一個後繼指針域
   }DuLonde, *Dulist;

 

雙鏈表的結點結構如圖2.14所示。

與單鏈表類似,雙鏈表一般也是有頭指針唯一確定的,增加頭結點也能使雙鏈表的某些運算變得方便。同時雙向鏈表也可以有循環表,稱爲雙向循環鏈表,其結構如圖2.15所示。

由於在雙向鏈表中既有前向鏈又有後向鏈,尋找任一個結點的直接前驅結點與直接後繼結點變得非常方便。設指針p指向雙鏈表中某一結點,則有下式成立:

P->prior->next=p=p->next->prior

在雙向鏈表中,那些只涉及後繼指針的算法,如求表長度、取元素、元素定位等,與單鏈表中相應的算法相同,但對於前插和刪除操作則涉及到前驅和後繼兩個方向的指針變化,因此與單鏈表中的算法不同。

 

1.雙向鏈表的前插操作

算法描述:欲在雙向鏈表第i個結點之前插入一個新的結點,則指針的變化情況如圖2.16所示。

 

2.雙向鏈表的刪除操作

算法描述:欲刪除雙向鏈表中的第i個結點,則指針的變化情況如圖2.17所示。

 

 

#include <iostream>


using namespace std;
template <class T>
class DuList
{
public:
    DuList()
   {
        L = new DuLnode;//申請節點空間
        p = new DuLnode;
//        if(L == NULL)//判斷是否有足夠的空間
//            cout << "申請內存空間失敗" <<endl;
        L->next = L;//將next設置爲空,初始化長度
        L->prior = L;
        flag = 0;//查看循環列表數據終止標誌位
   }
    //建立一個線性雙向鏈表的存儲結構
    typedef struct DuLnode
   {
        T data;
        struct DuLnode *prior;//建立一個前趨指針域
        struct DuLnode *next;//建立一個後繼指針域
   }DuLonde, *Dulist;
    //頭插法建立雙鏈表
    Dulist LinkListCreatH()
    {
        while((cin >> data1) && (data1 != 0))//data1終止循環
        {
            p = new DuLnode;//關鍵一步重新分配一個指針節點
            p->data = data1;
            p->next = L->next;
            L->next = p;
            p->prior = L;
            //L->prior = p;
            flag++;
        }
        return L;
    }
//    //尾插法建立雙鏈表
//    Dulist LinkListCreatF()
//    {
//        while((cin >> data1) && (data1 != 0))//data1終止循環
//        {
//            p = new DuLnode;//關鍵一步重新分配一個指針節點
//            p->data = data1;
//            p->next = L->next;
//            L->next = p;
//            p->prior = L;
//            L->prior = p;
//        }
//        return L;
//    }
    //插入算法
    Dulist ListInsert_Dul(const int i, T e)//1<= i <= 表長+1,第i個位置之前插入元素e
    {
        s = new DuLnode;
       // p = new DuLnode;
        s->data = e;
        q = L->next;
        j = 0;
        while((q != L) && j<i-1)
        {
            q = q->next;
            ++j;//尋找i-1節點
        }
        if(!p  || j>i)
        {
            cout << "error insert!" << endl;
            return L;
        }
        s->prior = q->prior;//插入L
        q->prior->next = s;
        s->next = q;
        q->prior = s;
        return L;
    }
    //刪除算法
    Dulist ListDelete_Dul(int i,  T &e)
    {
        q = L->next;
        j = 0;
        while((q != L) && j<i-1)
        {
            q = q->next;
            ++j;//尋找i-1節點
        }
        if(!p  || j>i)
        {
            cout << "error insert!" << endl;
            return L;
        }
        e = q->data;
        q->prior->next = q->next;
        q->next->prior = q->prior;
        return L;
    }
    //獲取元素
    void GetElem_L(int i, T &e)
    {//L帶頭結點的單鏈表指針,第i個元素存在時賦給e並返回OK,否則返回ERROR
        p = L->next;//初始化,p指向第一個節點
        j = 1;
        while(p != L && j<i)
        {
            p = p->next;
            ++j;
        }
        if(!p || j>i)
        {
            cout << "error getelem!" << endl;
        }
        e = p->data;
    }
    void showdata()
    {
      p = new DuLnode;
      j = 0;
      p = L->next;//指向頭結點的下一個節點
      while(p != L )
         {
          cout << p->data << " ";
          p = p->next;
          j++;
         }
    }
    ~DuList()
    {
        delete p;
        delete L;
        delete s;
        delete q;
    }
private:
    T data1;
    int j;
    int flag;
    DuLnode *p;
    DuLnode *L;
    DuLnode *s;
    DuLnode *q;
};
int main()
{
//    cout << "Hello World!" << endl;
    int data1;
    DuList<int> *list = new DuList<int>;
    //頭插法
    cout << "(H)please enter numbers or chars or strings: " << endl;
    list->LinkListCreatH();
    cout << "show linklist data:" << endl;
    list->showdata();
    cout << endl;
    //插入某值
    cout << "after insert numbers or chars or strings " << endl;
    list->ListInsert_Dul(3,10);
    cout << "show linklist data:" << endl;
    list->showdata();
    cout << endl;
    //刪除某值
    cout << "delete numbers or chars or strings: " << endl;
    list->ListDelete_Dul(3,data1);
    cout << "delete data: " << data1 << endl;
    list->showdata();
    cout << endl;
    return 0;
}
 
主要參照地址:
http://www.csdn123.com/html/exception/726/726589_726592_726583.htm
http://blog.csdn.net/abclixu123/article/details/8218465
http://blog.sina.com.cn/s/blog_77795cad01011ud1.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章