本文轉載自趣學算法,方便個人學習參考使用 http://blog.csdn.net/rainchxy/article/details/77946835
數據結構 第3講 順序表
順序表是最簡單的一種線性結構,邏輯上相鄰的數據在計算機內的存儲位置也是相鄰的,可以快速定位第幾個元素,中間不允許有空,所以插入、刪除時需要移動大量元素。
順序表可以分配一段連續的存儲空間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):
完整代碼
1 #include <iostream> 2 using namespace std; 3 #define Maxsize 100//最大空間 4 typedef struct{ 5 int *elem; 6 int length;//順序表長度 7 }SqList; 8 9 bool InitList(SqList &L) //構造一個空的順序表L 10 {//L加&表示引用類型參數,函數內部的改變跳出函數依然有效 11 //不加&表示內部改變,跳出函數后無效 12 L.elem=new int[Maxsize];//為順序表分配Maxsize 個空間 13 if(!L.elem) return false;//存儲分配失敗 14 L.length=0; 15 return true; 16 } 17 18 bool CreateList(SqList &L)//創建一個順序表L 19 { 20 int a,i=0; 21 cin>>a; 22 while(a!=-1){ 23 if(L.length==Maxsize){ 24 cout<<"順序表已滿! "; 25 return false; 26 } 27 L.elem[i++]=a; 28 L.length++; 29 cin>>a; 30 } 31 return true; 32 } 33 34 bool GetElem(SqList L,int i,int &e){ 35 if(i<1||i>L.length) return false; 36 //判斷i值是否合理,若不合理,返回false 37 e=L.elem[i-1];//第i-1的單元存儲着第i個數據 38 return true; 39 } 40 41 int LocateElem(SqList L,int x){ 42 for(int i=0;i<L.length;i++) 43 if(L.elem[i]==x) return i+1;//第幾個元素,例如第五個元素,下標其實為4 44 return -1; 45 } 46 47 bool ListInsert_Sq(SqList &L,int i,int e) 48 { 49 if(i<1||i>L.length+1) return false;//i值不合法 50 if(L.length == Maxsize) return false;//存儲空間已滿 51 for(int j=L.length-1;j>=i-1;j--) 52 L.elem[j+1]=L.elem[j];//從最后一個元素開始后移,直到第i個元素后移 53 L.elem[i-1]=e;//將新元素e放入第i個位置 54 L.length++;//表長加1 55 return true; 56 } 57 58 bool ListDelete_Sq(SqList &L,int i,int &e) 59 { 60 if((i<1)||(i>L.length)) return false;//i值不合法 61 e=L.elem[i-1];//將欲刪除的元素保留在e中 62 for(int j=i;j<=L.length-1;j++) 63 L.elem[j-1]=L.elem[j];//被刪除元素之后的元素后移 64 L.length--;//表長減少1 65 return true; 66 } 67 68 void print(SqList L) 69 { 70 cout<<"輸出順序表"<<endl; 71 for(int j=0;j<=L.length-1;j++) 72 cout<<L.elem[j]<<" "; 73 cout<<endl; 74 } 75 76 void DestroyList(SqList &L){ 77 if(L.elem) delete []L.elem;//釋放存儲空間 78 } 79 80 int main() 81 { 82 SqList myL; 83 int i,e,x; 84 cout<<"1.初始化\n"; 85 cout<<"2.創建\n"; 86 cout<<"3.取值\n"; 87 cout<<"4.查找\n"; 88 cout<<"5.插入\n"; 89 cout<<"6.刪除\n"; 90 cout<<"7.輸出\n"; 91 cout<<"8.銷毀\n"; 92 cout<<"0.退出\n"; 93 94 int choose = -1; 95 while(choose != 0){ 96 cout<<"請選擇:"; 97 cin>>choose; 98 switch(choose){ 99 case 1://初始化順序表 100 cout<<"順序表初始化·····"<<endl; 101 if(InitList(myL)) 102 cout<<"順序表初始化成功!"<<endl; 103 else 104 cout<<"順序表初始化失敗!"<<endl; 105 break; 106 case 2://創建順序表 107 cout<<"順序表創建····"<<endl; 108 cout<<"輸入整型數,輸入-1結束"<<endl; 109 if(CreateList(myL)) 110 cout<<"順序表創建成功!"<<endl; 111 else 112 cout<<"順序表創建失敗!"<<endl; 113 break; 114 case 3://取值 115 cout<<"輸入整型數i,取第i個元素輸出"<<endl; 116 cin>>i; 117 if(GetElem(myL,i,e)) 118 cout<<"第i個元素是:"<<e<<endl; 119 else 120 cout<<"順序表取值失敗!"<<endl;; 121 cout<<"第i個元素是:"<<e<<endl; 122 break; 123 case 4://查找 124 cout<<"請輸入要查找的數x:"; 125 cin>>x; 126 if(LocateElem(myL,x)==-1) 127 cout<<"查找失敗!"<<endl; 128 else 129 cout<<"查找成功!"<<endl; 130 break; 131 case 5://插入 132 cout<<"請輸入要插入的位置和要插入的數據元素e:"; 133 cin>>i>>e; 134 if(ListInsert_Sq(myL,i,e)) 135 cout<<"插入成功!"<<endl; 136 else 137 cout<<"插入失敗!"<<endl; 138 break; 139 case 6://刪除 140 cout<<"請輸入要刪除的位置i:"; 141 cin>>i; 142 if(ListDelete_Sq(myL,i,e)) 143 cout<<"刪除成功!"<<endl; 144 else 145 cout<<"刪除失敗!"<<endl; 146 break; 147 case 7://輸出 148 print(myL); 149 break; 150 case 8://銷毀 151 cout<<"順序表銷毀·····"<<endl; 152 DestroyList(myL); 153 break; 154 } 155 } 156 return 0; 157 } 158