C++語言實現(xiàn)順序表

C++語言實現(xiàn)順序表

順序表的定義及其特點

順序表的定義是:把線性表中的所有表項按照其邏輯順序依次存儲到從計算機存儲中指定存儲位置開始的一塊連續(xù)的存儲空間中效斑。 這樣,線性表中第一個表項的存儲位置就是被指定的存儲位置,第i個表項(2\leq i \leqn)的存儲位置緊接在第i一1個表項的存儲位置的后面。假設(shè)順序表中每個表項的數(shù)據(jù)類型為T,則每個表項所占用存儲空間的大小(即字節(jié)數(shù))大小相同,均為 sizeof(T),整個順序表所占用存儲空間的大小為n\times sizeof(T),其中n表示線性表的長度。

順序表的特點是:

(1)在順序表中,各個表項的邏輯順序與其存放的物理順序一致,即第i個表項存儲于
第i個物理位置(1\leq i \leqn).
(2)對順序表中所有表項,既可以進行順序訪問,也可以進行隨機訪問苗踪。 也就是說,既可以從表的第一個表項開始逐個訪問表項,也可以按照表項的序號(亦稱為下標(biāo))直接訪問表項捂襟。

順序表類定義及其主要操作

順序表的類聲明
class SeqList
{
    private:
        T *data;//存放數(shù)據(jù)的動態(tài)數(shù)組
        int maxSize;//最大可容納表項的項數(shù)
        int last; //當(dāng)前已存表項的最后位置(從0開始)
        void reSize(int newSize);   //改變數(shù)組空間大小
        
    public:
        SeqList(int sz);          //構(gòu)造函數(shù)
        SeqList(SeqList<T>& L);            //復(fù)制構(gòu)造函數(shù)
        ~SeqList() {delete[ ] data;}            //析構(gòu)函數(shù)
        int Size(){//求表最大容量
            return maxSize;
            }    
        int Length() {//計算表長度
            return last+1;
            }        
        int Search(T x);//搜索x在表中位置,函數(shù)返回表項序號 
        int Locate(int i);//定位第i個表項趴酣,函數(shù)返回表項序號
        bool Insert(int i, T& x);//插入x在第i個表項之后
        bool Remove(int i, T& x);//刪除第i個表項之后梨树,通過x返回表項的值
        bool GetData(int i,T& x);//取第i個表項的值,以x引用返回
        bool SetData(int i,T& x);//用x修改第i個表項的值
        bool IsEmpty(){//判斷表是否空否岖寞,是返回true抡四,否返回false
            return (last==-1) ? true : false;
        }
        bool IsFull(){//判讀表是否滿否,是返回true,否返回false
            return (last = maxSize - 1) ? true : false;
        }
        void input();//輸入數(shù)據(jù)
        void output();//打印數(shù)據(jù)
};

構(gòu)造函數(shù)和復(fù)制構(gòu)造函數(shù)
template <class T>
inline SeqList<T>::SeqList(int sz)
{
    if (sz > 0) {
        maxSize = sz;  last = -1;
        data = new T[maxSize];     //創(chuàng)建表存儲數(shù)組
        if (data == NULL)          //動態(tài)分配失敗
        { 
            cout<<"儲存分配錯誤指巡!"<<endl;
        }
    }
}
template <class T>
inline SeqList<T>::SeqList(SeqList<T>& L)
{
    //復(fù)制構(gòu)造函數(shù)淑履,用參數(shù)表中給出的已有順序表初始化新建的順序表
    maxSize = L.Size();
    last = L.Length()-1;
    T value;
    data = new T[maxSize];//創(chuàng)建順序表儲存數(shù)組
    if(data == NULL){
        cout<<"動態(tài)分配錯誤!"<<endl;
    }
    for(int i =1;i<=last-1;i++){
        L.GetData(i, value);
        data[i-1] = value;
    }
    
}

調(diào)整順序表空間大小
template <class T>
inline void SeqList<T>::reSize(int newSize){
    //私有函數(shù)藻雪,擴充順序表的儲存數(shù)組空間的大小秘噪,新數(shù)組的元素個數(shù)為newSize.
    if(newSize <= 0){
        cout<<"無效數(shù)組的大小勉耀!"<<endl;
    }
    if(newSize != maxSize){
        T *newarray = new T[newSize];
        if(newarray == NULL){
            cout<<"儲存分配錯誤指煎!"<<endl;
        }
        int n = last+1;
        T *srcptr = data;//源數(shù)組的首地址
        T *desptr = newarray;//目的數(shù)組的首地址
        while(n--){//復(fù)制
            *desptr++ = *srcptr++;
        }
        delete []data;//刪除老數(shù)組
        data = newarray;
        maxSize = newSize;//復(fù)制新數(shù)組
    }
}

搜索和定位操作
template <class T>
inline int SeqList<T>::Search(T x)
{
    //搜索函數(shù):在表中順序搜索與給定值x匹配的表項,找到則函數(shù)返回該表項是第幾個元素
    //否則返回0便斥,表示搜索失敗
    for(int i=0;i<=last;i++){
        if(data[i] == x)
        return i+1;
    }
    return 0;
}
template <class T>
inline int SeqList<T>::Locate(int i)
{
    //定位函數(shù):返回第i(1<=i<=lat+1)個表項的位置至壤,否則函數(shù)返回0,表示定位失敗
    if(i>=1 && i<last+1){
        return i;
    }
    else return 0;
}

插入與刪除操作
template <class T>
inline bool SeqList<T>::Insert(int i, T& x)//插入x在第i個表項之后
{
    //將新元素x插入到第i(0<=i<=last+1)個表項之后枢纠。函數(shù)返回插入成功的信息像街,若插入成功返回true,否則返回false.
    //i=0時虛擬的,實際上是插入到第1個元素的位置晋渺。
    if(last == maxSize - 1){
        return false;//表滿镰绎,不能插入
    }
    if(i<0 || i > last+1)
    {
        return false;//參數(shù)i不合理,不能插入
    }
    for(int j=last;j>=i;j--)
    {
        data[j+1]=data[j];//一次后移木西,空出第i號位置
    }
    data[i] = x;//插入
    last++;//最后位置加一
    return true;
}
template <class T>
inline bool SeqList<T>::Remove(int i, T& x)//刪除第i個表項之后畴栖,通過x返回表項的值
{
    //從表中刪除第i(0<=i<=last+1)個表項,通過引用型參數(shù)x返回刪除的元素值户魏。函數(shù)返回刪除成功的信息驶臊,刪除成功返回true,刪除失敗返回false
    if(last == -1){
        return false;//表空,不能刪除
    }
    if(i<1 || i>last+1){
        return false;//參數(shù)i不合理叼丑,不能刪除
    }
    x=data[i];//儲存刪除的元素
    for(int j=i;j<=last;j++)
    {
        data[j-1] = data[j];//依次前移关翎,填補
    }
    last--;//最后位置減一
    return true;
}

順序表的性能分析

順序表所有操作的實現(xiàn)中,最復(fù)雜、最耗時的就是搜索鸠信、插入和刪除運算的實現(xiàn)代碼纵寝。分析順序表的性能,主要是分析這3個操作的實現(xiàn)代碼的時間復(fù)雜性。
int search(T& x)是順序表的順序搜索算法星立。 其主要思想是:

從表的開始位置起,根據(jù)給定值x,逐個與表中各表項的值進行比較爽茴。 若給定值與某個表項的值相等,則算法報告搜索成功的信息并返回該表項的位置;若查遍表中所有的表項,沒有任何一個表項滿足要求,則算法報告搜索不成功的信息并返回0(必要的話,可改一下算法,返回新表項應(yīng)插人的位置)。

搜索算法的時間代價用數(shù)據(jù)比較次數(shù)來衡量绰垂。 在搜索成功的情形下,順序搜索的數(shù)據(jù)比較次數(shù)可做如下分析室奏。 若要找的正好是表中第1個表項,數(shù)據(jù)比較次數(shù)為1,這是最好情況;若要找的是表中最后的第n個表項,數(shù)據(jù)比較次數(shù)為n(設(shè)表的長度為n),這是最壞的情況 。若要計算平均數(shù)據(jù)比較次數(shù),需要考慮各個表項的搜索概率p及找到該表項時的數(shù)據(jù)比較次數(shù)p_i.搜索的平均數(shù)據(jù)比較次數(shù)ACN(average comparing number)為
ACN=\sum_{i=1}^n {p_i}\times c_i

計算平均數(shù)據(jù)比較次數(shù)是為了了解對表操作的整體性能劲装。若考慮相等概率的情形胧沫。搜索各表項的可能性相同,有p_1=p_2=...=p_n=\frac1 n,且搜索第1個表項的數(shù)據(jù)比較次數(shù)為1,搜計算平均值是為了解算法對表操作的整體性能昌简。 若僅考慮相等概率的情形。搜索各表索第2個表項的數(shù)據(jù)比較次數(shù)為2,,搜索第i號表項的數(shù)據(jù)比較次數(shù)為i,則
ACN=\frac1 n\sum_{i=1}^ni=\frac1 n(1+2+3+...+n)==\frac{1+n} 2
即平均要比較\frac{n+1} 2個表項绒怨。

分析順序表的插入和刪除的時間代價主要看循環(huán)內(nèi)的數(shù)據(jù)移動次數(shù)
在將新表項插入到第i個表項(0\leq i \leqn)后面時,必須從后向前循環(huán),逐個向后移動n-i個表項纯赎。 因此,最好的情形是在第n個表項后追加新表項,移動表項個數(shù)為0;最差情形是在第1個表項位置插人新表項(視為在第0個表項后面插入),移動表項個數(shù)為n;平均數(shù)據(jù)移動次數(shù)AMN(average moving number)在各表項插入概率相等時為
AMN=\frac1 {n+1}\sum_{i=0}^n{(n-i)}=\frac1 {n+1}\frac{n (n+1)} 2=\frac n 2
即就整體性能來說,在插入時有n+1個插入位置,平均移動\frac n 2個表項!

在刪除第i個表項(1\leq i \leqn)時,必須從前向后循環(huán),逐個移動n一i個表項。 因此,最好的情形是刪去最后的第n個表項,移動表項個數(shù)為0;最差情形是刪去第1個表項,移動項個數(shù)為n-1;平均數(shù)據(jù)移動次數(shù)AMN在各表項刪除概率相等時為
AMN=\frac1 n\sum_{i=1}^n{(n-i)}=\frac1 {n}\frac{n (n-1)} 2=\frac {n-1} 2
就整體性能來說,在刪除時有n個刪除位置,平均移動(n-1)/2個表項南蹂。

以上是C++順序表使用過程中最常用的主要操作犬金,相關(guān)完整代碼已經(jīng)push到GitHub,需要的小伙伴自行clone六剥,如果覺得還不錯的話晚顷,歡迎Star,這里是傳送門C++順序表,除此之外仗考,想要了解更多的C,C++,Java,Python等相關(guān)知識的童鞋音同,歡迎來我的博客相逢的博客词爬,我們一起討論秃嗜!接下來我會更新C語言鏈?zhǔn)浇Y(jié)構(gòu)實現(xiàn)線性表,敬請期待顿膨!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末锅锨,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子恋沃,更是在濱河造成了極大的恐慌必搞,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件囊咏,死亡現(xiàn)場離奇詭異恕洲,居然都是意外死亡,警方通過查閱死者的電腦和手機梅割,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門霜第,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人户辞,你說我怎么就攤上這事泌类。” “怎么了底燎?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵刃榨,是天一觀的道長。 經(jīng)常有香客問我双仍,道長枢希,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任朱沃,我火速辦了婚禮苞轿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己呕屎,他們只是感情好让簿,可當(dāng)我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著秀睛,像睡著了一般尔当。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蹂安,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天椭迎,我揣著相機與錄音,去河邊找鬼田盈。 笑死畜号,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的允瞧。 我是一名探鬼主播简软,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼述暂!你這毒婦竟也來了痹升?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤畦韭,失蹤者是張志新(化名)和其女友劉穎疼蛾,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體艺配,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡察郁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了转唉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片皮钠。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖酝掩,靈堂內(nèi)的尸體忽然破棺而出鳞芙,到底是詐尸還是另有隱情,我是刑警寧澤期虾,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布原朝,位于F島的核電站,受9級特大地震影響镶苞,放射性物質(zhì)發(fā)生泄漏喳坠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一茂蚓、第九天 我趴在偏房一處隱蔽的房頂上張望壕鹉。 院中可真熱鬧剃幌,春花似錦、人聲如沸晾浴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽脊凰。三九已至抖棘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間狸涌,已是汗流浹背切省。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留帕胆,地道東北人朝捆。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像懒豹,于是被迫代替她去往敵國和親芙盘。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容