數據結構——順序表(內含代碼,解析)

順序表是最簡單的一種線性結構,邏輯上相鄰的數據在計算機內的存儲位置也是相鄰的,可以快速定位第幾個元素,中間不允許有空,所以插入、刪除時需要移動大量元素。

順序表可以分配一段連續的存儲空間Maxsize,用elem記錄基地址,用length記錄實際的元素個數,即順序表的長度,

結構體的定義:

結構體定義後,如果要定義個順序表L,就可以寫:

SqList L;

1. 順序表初始化

初始化是指給順序表分配一個預定義大小的空間,用基地址elem記錄這段空間的首地址,裏面什麼都沒用,元素個數爲0。前面我們已經預定義好了一個最大空間數Maxsize,那麼就用new分配這麼大的空間,分配成功會返回空間的首地址。假設順序表裏面需要存儲整型數,那麼就可以這樣初始化:

boolInitList(SqList &L) //構造一個空的順序表L

{   //L加&表示引用類型參數,函數內部的改變跳出函數仍然有效

    //不加&內部改變,跳出函數後無效

    L.elem=new int[Maxsize];    //爲順序表分配Maxsize個空間

    if(!L.elem) return false;      //存儲分配失敗

    L.length=0;                          //空表長度爲0

    return true;

}

2. 順序表創建

順序表創建是向順序表中輸入數據,輸入數據的類型要與類型定義中的類型一致。假設順序表裏面需要存儲整型數,那麼就可以這樣創建:

boolCreateList(SqList &L) //創建一個順序表L

{   //L加&表示引用類型參數,函數內部的改變跳出函數仍然有效

    //不加&內部改變,跳出函數後無效

    int a,i=0;

   while(a!=-1)

   {

       cin>>a;

      if(L.length==Maxsize)

     {

          cout<<”順序表已滿!”

          return false;

     }

    L.elem[i++]=a;

      L.length++;

   }

    return true;

}

3. 順序表取值

順序表中的任何一個元素都可以立即找到,稱爲隨機存取方式,例如我們我取第i個元素,只要i值是合理的(1≤i≤L.length),那麼立即就可以找到該元素L.elem[i-1]:

bool GetElem(SqList L,int i,int &e)

{

    if (i<1||i>L.length) return false;

      //判斷i值是否合理,若不合理,返回false

    e=L.elem[i-1]; //第i-1的單元存儲着第i個數據

   return true;

}

4. 順序表查找

在順序表中查找一個元素e,需要從第一個元素開始順序查找,依次比較每一個元素值,如果相等,則返回元素位置(第幾個元素),如果查找整個順序表都沒找到,則返回-1:

int LocateELem(SqList L,int e)

{

   for (i=0;i< L.length;i++)

       if (L.elem[i]==e) return i+1; //第幾個元素,例如第5個元素,下標其實爲4

  return -1;

}

 

時間複雜性分析:

最好情況:如果元素正好在第一個位置,一次比較成功;時間複雜度爲O(1);

最壞情況:如果元素正好在最後一個位置,需要比較n次成功,時間複雜度爲O(n);

平均情況:假設每個元素查找概率均等,在第一個位置需要比較1次,第二個位置需要比較2次,…,最後一個位置,需要比較n次,把n種情況加起來平均,平均時間複雜度也爲O(n):

5. 順序表插入

在順序表中第i個位置之前插入一個元素e,需要從最後一個元素開始後移,…,直到把第i個元素也後移一位,然後把e放入第i個位置。

(1)判斷插入位置i是否合法(1≤i≤L.length+1),可以在第n+1個元素之前插入。

(2)判斷順序表的存儲空間是否已滿。

(3)將第n至第i 位的元素依次向後移動一個位置,空出第i個位置。

(4)將要插入的新元素e放入第i個位置。

(5)表長加1,插入成功返回true。

bool ListInsert_Sq(SqList &L,int i ,int e)

{

   if(i<1 || i>L.length+1) return false;     //i值不合法

   if(L.length==Maxsize) return false; //存儲空間已滿

   for(j=L.length-1;j>=i-1;j--)

      L.elem[j+1]=L.elem[j]; //從最後一個元素開始後移,直到第i個元素後移

   L.elem[i-1]=e; //將新元素e放入第i個位置

   L.length++;             //表長增1

  return true;

}

時間複雜性分析:

假設每個位置插入的概率均等,可以在第一個位置之前插入,第二個位置之前插入,…,最後一個位置之前,第n+1個位置之前,一共有n+1種情況,每種情況移動元素的個數是n-i+1,把所有情況加起來平均,平均時間複雜度爲O(n):

6. 順序表刪除

在順序表中刪除第i個元素,需要把該元素暫存到變量e,然後從i+1個元素開始前移,…,直到把第n個元素也前移一位,然後把e放入第i個位置。

(1)判斷插入位置i是否合法(1≤i≤L.length)。

(2)將欲刪除的元素保留在e中。

(3)將第i+1至第n 位的元素依次向前移動一個位置。

(4)表長減1,刪除成功返回true。

bool ListDelete_Sq(SqList &L,int i, int &e)

{

   if((i<1)||(i>L.length)) return false;     //i值不合法

  e=L.elem[i-1]; //將欲刪除的元素保留在e中

  for (j=i;j<=L.length-1;j++)

   L.elem[j-1]=L.elem[j]; //被刪除元素之後的元素前移

  L.length--;      //表長減1

  return true;

}

時間複雜性分析:

假設刪除每個元素的概率均等,一共有n種情況,每種情況移動元素的個數是n-i,把所有情況加起來平均,平均時間複雜度爲O(n):


完整代碼

#include <iostream>

using namespace std;

 

#define  Maxsize 100  //最大空間

 

typedef struct{

  int *elem;

  int length;       // 順序表的長度

}SqList;

 

bool InitList(SqList &L) //構造一個空的順序表L

{   //L加&表示引用類型參數,函數內部的改變跳出函數仍然有效

//不加&內部改變,跳出函數後無效

    L.elem=new int[Maxsize];    //爲順序表分配Maxsize個空間

    if(!L.elem) return false;      //存儲分配失敗

    L.length=0;                          //空表長度爲0

    return true;

}

 

bool CreateList(SqList &L) //創建一個順序表L

{   //L加&表示引用類型參數,函數內部的改變跳出函數仍然有效

//不加&內部改變,跳出函數後無效

    int a,i=0;

    cin>>a;

    while(a!=-1)

    {

     if(L.length==Maxsize)

     {

       cout<<"順序表已滿!";

       return false;

     }

     L.elem[i++]=a;

     L.length++;

     cin>>a;

   }

   return true;

}

 

bool GetElem(SqList L,int i,int &e)

{

  if (i<1||i>L.length) returnfalse;

   //判斷i值是否合理,若不合理,返回false

  e=L.elem[i-1];   //第i-1的單元存儲着第i個數據

  return true;

}

 

int LocateELem(SqList L,int x)

{

  for (int i=0;i<L.length;i++)

      if (L.elem[i]==x) return i+1;//第幾個元素,例如第5個元素,下標其實爲4

  return -1;

}

 

bool ListInsert_Sq(SqList &L,int i ,int e)

{

   if(i<1 || i>L.length+1)return false; //i值不合法

   if(L.length==Maxsize) returnfalse; //存儲空間已滿

   for(intj=L.length-1;j>=i-1;j--)

       L.elem[j+1]=L.elem[j];   //從最後一個元素開始後移,直到第i個元素後移

   L.elem[i-1]=e;              //將新元素e放入第i個位置

   L.length++;                      //表長增1

   return true;

}

 

bool ListDelete_Sq(SqList &L,int i,int &e)

{

   if((i<1)||(i>L.length))return false;  //i值不合法

   e=L.elem[i-1];   //將欲刪除的元素保留在e中

   for (int j=i; j<=L.length-1; j++)

              L.elem[j-1] =L.elem[j]; //被刪除元素之後的元素前移

   L.length--; //表長減1

   return true;

}

 

void print(SqList L)

{

   cout << "輸出順序表" <<endl;

   for(int j=0;j<=L.length-1;j++)

    cout<<L.elem[j]<<"  ";

   cout<<endl;

}

 

void DestroyList(SqList &L)

{

  if (L.elem) delete []L.elem;    //釋放存儲空間

}

 

int main()

{

    SqList myL;

    int i,e,x;

    cout << "1. 初始化\n";

       cout << "2. 創建\n";

       cout << "3. 取值\n";

       cout << "4. 查找\n";

       cout << "5. 插入\n";

       cout << "6. 刪除\n";

       cout << "7. 輸出\n";

       cout << "8. 銷燬\n";

       cout << "0. 退出\n";

 

       int choose = -1;

       while (choose != 0)

       {

        cout << "請選擇:";

              cin >> choose;

              switch (choose)

              {

                  case 1://初始化順序表

                      cout << "順序表初始化..." <<endl;

                      if(InitList(myL))

                    cout <<"順序表初始化成功!" << endl;

                else

                    cout <<"順序表初始化失敗!" << endl;

                      break;

                   case 2://創建順序表

                       cout << "順序表創建..." <<endl;

                       cout << "輸入整型數,輸入-1結束" <<endl;

                       if(CreateList(myL))

                    cout <<"順序表創建成功!" << endl;

                 else

                    cout <<"順序表創建失敗!" << endl;

                 break;

            case 3://取值

                cout << "輸入整型數i,取第i個元素輸出" <<endl;

                cin>>i;

                if(GetElem(myL,i,e))

                    cout <<"第i個元素是: " <<e<< endl;

                 else

                    cout <<"順序表取值失敗!" << endl;;

                cout << "第i個元素是: "<<e<< endl;

                break;

            case 4://查找

                cout << "請輸入要查找的數x:";

                cin>>x;

               if(LocateELem(myL,x)==-1)

                    cout <<"查找失敗!" << endl;

                else

                    cout <<"查找成功!" << endl;

                break;

            case 5://插入

                cout << "請輸入要插入的位置和要插入的數據元素e:";

               cin>>i>>e;

               if(ListInsert_Sq(myL,i,e))

                    cout <<"插入成功!" << endl;

                else

                    cout <<"插入失敗!" << endl;

                break;

             case 6://刪除

                cout << "請輸入要刪除的位置i:";

                cin>>i;

               if(ListDelete_Sq(myL,i,e))

                    cout <<" 刪除成功!" << endl;

                else

                    cout <<"刪除失敗!" << endl;

                break;

            case 7://輸出

                print(myL);

                break;

            case 8://銷燬

                cout << "順序表銷燬..."<<endl;

                DestroyList(myL);

                break;

        }

       }

    return 0;

}
原文:https://blog.csdn.net/rainchxy/article/details/77946835 
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章