1. 程式人生 > >c++實現雙向連結串列,類模板雙向連結串列

c++實現雙向連結串列,類模板雙向連結串列

#include<iostream>
#include<assert.h>
using namespace std;

typedef int Datatype;
typedef struct Node//連結串列是由一個個節點組成所以這裡單獨定義這一型別方便在連結串列類中使用
{
     Datatype _data;
     struct Node* next;
     struct Node* prev;
}Node,*pNode;

typedef class LinkList
{
private:
     pNode head;
public:
     LinkList()
    {
      head=NULL;
    }

 void pushback(Datatype x)
 {
      pNode p=new Node[sizeof(Node)];
      p->_data=x;
      p->next=NULL;
      if(head==NULL)
     {
        head=p;
        head->prev=NULL;
     }
     else
    {
        pNode cur=head;
        while(cur->next)
       {
           cur=cur->next;
       }
       cur->next=p;
       p->prev=cur;
    }
 }

 void pushfront(Datatype x)
 {
      pNode tmp=new Node[sizeof(Node)];
      if(head==NULL)
     {
        tmp->_data=x;
        head=tmp;
        head->next= NULL;
        head->prev=NULL;
    }
      else
   {
     //我們要在頭結點前再插入一個結點,需要先建立一個新的結點,將頭結點的值儲存在新節點,然後讓新節點的下
     //個結點指向頭結點的下一個結點,再讓新節點的prev指向頭結點,這樣就將新節點與原來的連結串列融合了,然後我
     //們將頭結點的資料換成x即可。
        tmp->_data=head->_data;
        tmp->next=head->next;
        tmp->prev=head;//
        head->next=tmp;
        head->_data=x;
  }
 }
 void popback()
 {
      if(head!=NULL)
     {
       pNode cur=head;
       pNode pre=NULL;
       while(cur->next)
     {
       pre=cur;
       cur=cur->next;
     }
     delete[] cur;
     cur=NULL;
     pre->next=NULL;//一定要將pre->next置為空,前面一句僅僅是將cur的值置為空,此時pre->next還指向原來的那塊空間
  }
 }

 void popfront()
 {
      if(head!=NULL)
     {
        if(head->next==NULL)
       {
          delete[] head;
          head=NULL;
       }
     else
      {
         pNode del=head;
         head=head->next;
         delete[] del;
         del=NULL;//這裡將del置為空可以防止它變為野指標
      }
    }
 }

 pNode find(Datatype x)
 {
      if(head==NULL)
    {
      return NULL;
    }
      else
    {
       pNode cur=head;
       while(cur)
      {
         if(x==cur->_data)
        {
          return cur;
        }
         cur=cur->next;
      }
    return NULL;
  }
 }

 void insert(pNode pos,Datatype x)
 {
      assert(pos);//防止pos為空指標
      if(head==NULL)
     {
       return ;
     }
      else
     {
        pNode cur=head;
        if(head==pos)
       {
        pushfront(x);
       }
       else
       {
            while(cur)
          {
             if(cur==pos)
            {
             pNode tmp=new Node[sizeof(Node)];
             tmp->_data=cur->_data;
             tmp->next=cur->next;
             tmp->prev=cur;
             cur->_data=x;
             cur->next=tmp;
             return ;//insert成功後不要忘了直接返回結束函式
            }
            cur=cur->next;
         }
         cout<<"沒有找到這個數字"<<endl;
      }
   }
 }

 void erase(pNode pos)//刪除指定位置的結點
 {
      assert(pos);
      if(head==NULL)
     {
       return;
     }
     else
    {
        if(pos==head)
       {
         popfront();
       }
       else
      {
         pNode del=head->next;
         pNode pre=head;
         while(del)
        {
           if(del==pos)
           {
               if(del->next!=NULL)
             {
                pre->next=del->next;
                del->next->prev=pre;
                delete[] del;
                del=NULL;
             }
             else
            {
               delete[] del;
               pre->next=NULL;
            }
             return;
          }
         del=del->next;
         pre=pre->next;
      }
   }
  }
 }

 int use_count()//返回連結串列中結點的數量
 {
      int count=0;
      pNode cur=head;
      while(cur)
     {
       cur=cur->next;
       count++;
     }
     return count;
 }

 void display()//列印連結串列
 {
      pNode cur=head;
      while(cur!=NULL)
     {
       cout<<cur->_data<<endl;
       cur=cur->next;
     }
 }

 ~LinkList()
 {
      pNode cur=head;
      while(cur!=NULL)
     {
         pNode Next=cur->next;
         delete cur;
         cur=Next;
         if(cur!=NULL)
        {
          Next=Next->next;
        }
         else
           break;
     }
 }
};

void test()
{
     LinkList ls1;
     ls1.pushback(1);
     ls1.pushback(2);
     ls1.pushback(3);
     ls1.pushfront(0);
     ls1.display();
     ls1.popback();
     ls1.display();
     ls1.popfront();
     ls1.display();
     pNode ret=ls1.find(2);
     if(ret==NULL)
    {
      cout<<"沒有找到"<<endl;
    }
     else
    {
      cout<<ret->_data<<endl;
    }
    ls1.insert(ret,5);
    ls1.display();
    pNode ret2=ls1.find(2);
    ls1.erase(ret2);
    ls1.display();
    int ret3=ls1.use_count();
    cout<<ret3<<endl;
}

int main()
{
     test();
     getchar();
     return 0;
}

相關推薦

c++實現雙向連結串列模板雙向連結串列

#include<iostream> #include<assert.h> using namespace std; typedef int Datatype; typedef struct Node//連結串列是由一個個節點組成所以這裡單獨定義這一型別方便在連結串列類中使用 {  

C++ 模板小結(雙向連結串列模板實現

一、類模板定義 定義一個類模板:template<class 模板引數表> class 類名{ // 類定義...... };其中,template 是宣告類模板的關鍵字,表示宣告一個模板,模板引數可以是一個,也可以是多個,可以是型別引數,也可以是非型別引數。型

c++實現模板雙向連結串列

#include<iostream> #include<assert.h> using namespace std; typedef int Datatype; typedef struct Node //連結串列是由一個個節點組成所以這裡單獨定

雙向連結串列List---模板實現

class _ListIterator_ { public: typedef _ListIterator_<T,Ref,Pre> self; typedef ListNode<T>* LinkType; typedef Ref Reference; ty

二叉樹之二叉連結串列模板實現

該類模板實現了一個二叉樹的模板類,採用二叉連結串列實現。 定義二叉樹節點類,採用二叉連結串列實現。 [cpp] view plaincopyprint? ///////////////////////// #incl

[資料結構]二叉樹之二叉連結串列模板實現

該類模板實現了一個二叉樹的模板類,採用二叉連結串列實現。定義二叉樹節點類,採用二叉連結串列實現。///////////////////////// #include <iostream> #include <cstdlib> #include <

Java實現有環的單向連結串列並判斷單向連結串列是否有環

有一個單向連結串列,連結串列當中有可能出現環,就像下圖這樣。我們如何判斷一個單向連結串列是否有環呢? 那麼第一步,我們先實現一個這樣的連結串列,接著再說如何判斷這樣的連結串列。 實現有環的單向連結串列 1、定義add(Node node)方法 /**

C++模板初階(泛型程式設計函式模板模板)

1.泛型程式設計 怎麼實現一個通用的交換函式呢 使用函式過載雖然可以實現,但是有一下幾個不好的地方: 1. 過載的函式僅僅只是型別不同,程式碼的複用率比較低,只要有新型別出現時,就需要增加對應的函式 2. 程式碼的可維護性比較低,一個出錯可能所有的過載均出錯

c++ 模板函式模板仿函式使用例項程式碼

1.模板函式  #include <iostream> using namespace std; template <class T> T myMin(T x, T y) { return (x < y) ? x : y; } void ma

C++模板的特化(函式模板特化模板特化)與例項化區別聯絡

一:例項化什麼是例項化:一個通過使用具體值替換模板引數,從模板產生的普通類,函式的過程1.顯示例項化:通過指定的型別,表明要例項化的型別2.隱式例項化:通過編譯器自己推演,判斷出要例項化的型別 二 :特

C#實現用於生成條形碼的

clas res ssi win 聲明 plugin 鏈表 用法 style 本文實例講述了C#實現用於生成條形碼的類。分享給大家供大家參考。具體如下: 這個C#類可以用來生成39碼 12位標準條形碼using System.Collections; using Syst

函數模模板

排列 函數類 無法 round 推斷 typename 檢測 選擇 成員 函數模板特化 函數模板特化: 關鍵字template後面接一對<> 再接模板名和一對<>,尖括號中定義這個特華的模板參數 函數形參表 函數體 template <t

Essential c++ 第六章練習及模板template class 知識點

知識點: 1、類模板形式 template< typename elemType> class T ,其中typename可以替換為class,寫成template< class elemType> class T。 呼叫形式:T< string>t1

演算法題006 -- [將兩個排序的連結串列合併返回一個新連結串列返回的新連結串列也是排好序的] by java

題目 將兩個排序的連結串列合併,返回一個新連結串列,返回的新連結串列也是排好序的 程式碼 package algorithm6; public class Algorithm6 { public static void main(String[] args) {

C++實現的splite函式記錄便於查詢

記錄方便查詢 vector<string> splite(const string &s, const string &c)//分割字元用的 { std::string::size_type pos1, pos2; vector<stri

c++實現顏色空間rgbgreyluv和lab的互轉

1 rgb轉grey,rgb轉luv,rgb轉lab 1. 1 rgb轉grey     void RgbToGrey(unsigned char *rgb, double *grey) { double R = ((dou

Python-劍指offer(15,16)反轉連結串列合併兩個連結串列

題目:輸入一個連結串列,反轉連結串列後,輸出新連結串列的表頭。 環境:Python2.7.3 # -*- coding:utf-8 -*- # class ListNode: # def _

C#實現資料回滾A事件和B事件同時執行其中任何一個事件執行失敗都會返回失敗

  /// <summary> /// 執行資料庫回滾操作,用於sql語句執行失敗後,恢復執行前的資料 /// </summary> /// <param name="TableName">目標表</param> /// <param

各種排序演算法的場景以及c++實現(插入排序希爾排序氣泡排序快速排序選擇排序歸併排序)

對現有工作並不是很滿意,所以決定找下一個坑。由工作中遇到排序場景並不多,大都是用氣泡排序,太low,面試又經常問到一些排序演算法方面的東西。剛好讓小學妹郵的資料結構也到了。就把各種排序演算法重新總結一下,以作留存。 排序分為內部排序和外部排序,內部排序是在記憶體中排序。外

C++實現一個二叉樹

/**//** 昨天參加宜搜的筆試,要求用C++寫一二叉樹類,實現插入,刪除,定位功能,輾轉再三,* 卻無從下手,甚急,終基礎不好,今天再想,通過層次遍歷二叉樹,再進行實現相關功能* 實也不難. 以下程式碼*//**//** FileName:BTree.cpp* Description:binary tre