1. 程式人生 > 其它 >1.1線性表·順序表

1.1線性表·順序表

大家好,我是Koko~

資料結構是計算機儲存、組織資料的方式。資料結構是指相互之間存在一種或多種特定關係的資料元素的集合。通常情況下,精心選擇的資料結構可以帶來更高的執行或者儲存效率。 資料結構往往同高效的檢索演算法和索引技術有關。

本專欄將針對資料結構相關知識進行梳理及總結。建議搭配C語言版(嚴蔚敏版)資料結構教材使用更佳。


線性表是最常用且最簡單的一種資料結構。一個線性表是n個數據元素的有限序列。在稍複雜的線性表中,一個數據元素可以由若干個資料項組成。在這種情況下,常把資料元素稱為記錄,含有大量記錄的線性表又稱檔案。

同一線性表中的元素必定具有相同特性,即屬同一資料物件,相鄰資料元素之間存在著序偶關係。

1、線性結構的基本特徵:

線性邏輯結構的非形式化描述 一個數據元素的有序(次序)集



(1)集合中必存在唯一的一個“第一元素

(2)集合中必存在唯一的一個 “最後元素

(3)除最後元素在外,均有 唯一的後繼

(4)除第一元素之外,均有 唯一的前驅

2、線性表型別的儲存結構----順序對映

線性表具有兩種結構——順序結構鏈式結構。本節主要講解順序結構所對應的順序表

順序映象

以 x 的儲存位置和 y 的儲存位置之間某種關係表示邏輯關係<x,y>

通常情況順序映象方法是

令y的儲存位置和x的儲存位置相鄰。

一、順序表的定義

順序表,用一組地址連續的儲存單元依次儲存線性表的資料元素,它的邏輯地址相鄰,實體地址也相鄰(參照一維陣列)。

順序表的優點:簡單、支援隨機訪問、查詢方便、尾插和尾刪效率高。

順序表的缺點:資料的插入和刪除慢(需要挪動後面的資料)。

順序表的結構如下圖所示,它有兩個區域,一個是資料區域類似於陣列,存放使用者儲存的資料,另一個是一個整形變數區,存放已經使用了的區域個數。

定義順序表型別

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #define MAXSIZE 20
 4  
 5 //資料元素的型別
 6 typedef int ElemType;   
 7  
 8 //定義順序表型別
 9 typedef struct
10 { 11 ElemType a[MAXSIZE]; 12 int length; //順序表的實際長度 13 }SqList, *SqList;

二、順序表的基本操作函式

對順序表,有初始化、列印、插入、刪除、查詢的基本操作。

1、初始化順序表函式

1 Status Init_List(SqList &L)
2 {
3     memset(L.data, 0, sizeof(L));//初始化資料為0
4     L.length = 0;                //初始化長度為0
5     return 0;
6 }

2、建立順序表函式

 1 //建立線性表
 2 void Creat_List(SqList *L)
 3 {
 4     int i;
 5     printf("請輸入線性表的長度: ");
 6     scanf("%d",&L->length);
 7     for(i=0;i<L->length;i++)
 8     {
 9         printf("資料 %d =",i);
10             scanf("%d",&(L->a[i]));
11         }
12 }

3、輸出函式

1 //輸出線性表
2 void Out_List(SqList L)
3 {
4     int i;
5     for(i=0;i<=L.length-1;i++)
6         printf("%10d",L.a[i]);
7 }

4、插入函式(插入一個元素)

 1 //線上性表的第i個位置插入元素e
 2 void Insert_Sq(SqList *L,int i,ElemType e)
 3 {
 4     int j;
 5     if(L->length==MAXSIZE)
 6         printf("線性表已滿!\n");
 7     else 
 8         {
 9         if(i<1||i>L->length+1)
10                 printf("輸入位置錯!\n");
11         else 
12         {
13         for(j=L->length-1;j>=i-1;j--)
14                 L->a[j+1]=L->a[j];
15                 L->a[i-1]=e;   
16         L->length++;
17         }
18     }
19 }

5、刪除函式(刪除一個元素)

 1 //刪除第i個元素,返回其值
 2 ElemType Delete_Sq(SqList *L,int i)
 3 {
 4     ElemType x;
 5     int j;
 6     if(L->length==0)
 7         printf("空表!\n");
 8     else if(i<1||i>L->length)
 9     {
10         printf("輸入位置錯!\n");
11         x=-1;
12     }
13     else
14     {
15         x=L->a[i-1];
16         for(j=i;j<=L->length-1;j++)
17                     L->a[j-1]=L->a[j];
18                 L->length--;
19     }
20     return(x);
21 }

6、查詢函式(查詢一個值為e的元素,返回它的位置)

1 //查詢值為e的元素,返回它的位置
2 int Locate_Elem(SqList L,ElemType e)
3 {
4     int i=0;
5     while(L.a[i]!=e) 
6               i++;
7     if(i<=L.length-1)
8         return(i+1);
9 }

三、順序表的功能操作函式

1、倒置函式(將原順序表直接倒置)

 1 //倒置函式 將原順序表直接倒置
 2 void Reverse(SqList &L)
 3 {
 4     if (L.length)
 5         for (int i = 0; i<L.length - 1 - i; i++)
 6         {
 7             int t = L.data[i];
 8             L.data[i] = L.data[L.length - 1 - i];
 9             L.data[L.length - 1 - i] = t;
10         }
11 }

2、奇偶分開並排序

 1 //奇偶分開並排序
 2 void SplitSort(SqList &L)
 3 {
 4     int Even = 0;
 5     int Odd = L.length - 1;
 6     int i = 0;
 7     int j = L.length - 1;
 8     bool flag = false;
 9     if (L.length)
10         for (; i < j; i++, j--)
11         {
12             while (L.data[i] % 2 != 0)i++;
13             while (L.data[j] % 2 == 0)j--;
14             if (L.data[i] % 2 == 0 && L.data[j] % 2 != 0&&i<j)
15             {
16                 int temp = L.data[i];
17                 L.data[i] = L.data[j];
18                 L.data[j] = temp;
19                 flag = true;
20             }
21             if(!flag) //沒有交換
22             {
23                 Even = L.length - 1;//全奇數
24                 Odd = 0; //全偶數
25             }
26         }
27     if (flag)
28     {
29         for(int i=0;i<L.length;i++)
30             if (L.data[i] % 2 == 0) 
31             {
32                 Odd = i;
33                 Even = i - 1;
34                 break;
35             }
36     }
37     sort(L.data, L.data + Even + 1);
38     sort(L.data + Odd, L.data + L.length);
39 }

四、順序表操作總覽

  1 /*
  2 Project: sequence_list(資料結構-順序表)
  3 */
  4  
  5 #include<cstdio>
  6 #include<cstdlib>
  7 #include<cstring>
  8 #include<cmath>
  9 #include<algorithm>
 10 #include<iostream>
 11 #define MaxSize 100
 12 #define ElemType int
 13 #define Status int
 14 using namespace std;
 15  
 16 //順序表資料結構
 17 typedef struct
 18 {
 19     ElemType a[MAXSIZE];
 20     int length;    //順序表的實際長度
 21 }SqList, *SqList;  
 22  
 23 //***************************基本操作函式*******************************//
 24  
 25 //初始化順序表函式,構造一個空的順序表 
 26 Status Init_List(SqList &L)
 27 {
 28     memset(L.data, 0, sizeof(L));//初始化資料為0
 29     L.length = 0;                //初始化長度為0
 30     return 0;
 31 }
 32  
 33 //建立順序表函式 初始化前n個數據
 34 void Creat_List(SqList *L)
 35 {
 36     int i;
 37     printf("請輸入線性表的長度: ");
 38     scanf("%d",&L->length);
 39     for(i=0;i<L->length;i++)
 40     {
 41         printf("資料 %d =",i);
 42             scanf("%d",&(L->a[i]));
 43         }
 44 }
 45  
 46 //插入函式 位置i插入資料 i及之後元素後移  1=<i<=length+1 
 47 void Insert_Sq(SqList *L,int i,ElemType e)
 48 {
 49     int j;
 50     if(L->length==MAXSIZE)
 51         printf("線性表已滿!\n");
 52     else 
 53         {
 54         if(i<1||i>L->length+1)
 55                 printf("輸入位置錯!\n");
 56         else 
 57         {
 58         for(j=L->length-1;j>=i-1;j--)
 59                 L->a[j+1]=L->a[j];
 60                 L->a[i-1]=e;   
 61         L->length++;
 62         }
 63     }
 64 }
 65  
 66 //刪除函式 刪除位置i的元素 i之後的元素依次前移
 67 ElemType Delete_Sq(SqList *L,int i)
 68 {
 69     ElemType x;
 70     int j;
 71     if(L->length==0)
 72         printf("空表!\n");
 73     else if(i<1||i>L->length)
 74     {
 75         printf("輸入位置錯!\n");
 76         x=-1;
 77     }
 78     else
 79     {
 80         x=L->a[i-1];
 81         for(j=i;j<=L->length-1;j++)
 82                     L->a[j-1]=L->a[j];
 83                 L->length--;
 84     }
 85     return(x);
 86 }
 87  
 88 //查詢函式 按位置從小到大查詢第一個值等於e的元素 並返回位置
 89 int Locate_Elem(SqList L,ElemType e)
 90 {
 91     int i=0;
 92     while(L.a[i]!=e) 
 93               i++;
 94     if(i<=L.length-1)
 95         return(i+1);
 96 }
 97  
 98 //倒置函式 將原順序表直接倒置
 99 void Reverse(SqList &L)
100 {
101     if (L.length)
102         for (int i = 0; i<L.length - 1 - i; i++)
103         {
104             int t = L.data[i];
105             L.data[i] = L.data[L.length - 1 - i];
106             L.data[L.length - 1 - i] = t;
107         }
108 }
109  
110 //奇偶分開並排序
111 void SplitSort(SqList &L)
112 {
113     int Even = 0;
114     int Odd = L.length - 1;
115     int i = 0;
116     int j = L.length - 1;
117     bool flag = false;
118     if (L.length)
119         for (; i < j; i++, j--)
120         {
121             while (L.data[i] % 2 != 0)i++;
122             while (L.data[j] % 2 == 0)j--;
123             if (L.data[i] % 2 == 0 && L.data[j] % 2 != 0&&i<j)
124             {
125                 int temp = L.data[i];
126                 L.data[i] = L.data[j];
127                 L.data[j] = temp;
128                 flag = true;
129             }
130             if(!flag) //沒有交換
131             {
132                 Even = L.length - 1;//全奇數
133                 Odd = 0; //全偶數
134             }
135         }
136     if (flag)
137     {
138         for(int i=0;i<L.length;i++)
139             if (L.data[i] % 2 == 0) 
140             {
141                 Odd = i;
142                 Even = i - 1;
143                 break;
144             }
145     }
146     sort(L.data, L.data + Even + 1);
147     sort(L.data + Odd, L.data + L.length);
148 }
149  
150 //清空順序表
151 void ClearList(SqList &L) {
152     L.length = 0;
153 }
154  
155 //********************************功能函式*****************************************//
156  
157 //輸出功能函式 按位置從小到大輸出順序表所有元素
158 void Out_List(SqList L)
159 {
160     int i;
161     for(i=0;i<=L.length-1;i++)
162         printf("%10d",L.a[i]);
163 }
164  
165 //建立順序表函式
166 void Create(SqList &L)
167 {
168     int n; bool flag;
169     L.length = 0;
170     printf("請輸入要建立的順序表長度(>1):");
171     scanf("%d", &n);
172     printf("請輸入%d個數(空格隔開):", n);
173     flag = CreateList(L, n);
174     if (flag) {
175         printf("建立成功!\n");
176         PrintList(L);
177     }
178     else printf("輸入長度非法!\n");
179  
180 }
181  
182 //插入功能函式 呼叫Insert_Sq完成順序表元素插入 呼叫Out_List函式顯示插入成功後的結果
183 void Insert(SqList &L,int place, ElemType e)
184 {
185     bool flag;
186     printf("請輸入要插入的位置(從1開始)及元素:\n");
187     scanf("%d%d", &place, &e);
188     flag = Insert_Sq(L, place, e);
189      if (flag)
190     {
191         printf("插入成功!!!\n");
192         PrintList(L);
193     }
194 }
195  
196 //刪除功能函式 呼叫Delete_Sq函式完成順序表的刪除 呼叫Out_List函式顯示插入成功後的結果
197 void Delete(SqList &L,int place;)
198 {
199         bool flag;
200     printf("請輸入要刪除的位置(從1開始):\n");
201     scanf("%d", &place);
202     flag = Delete_Sq(L, place);
203     if (flag)
204     {
205         printf("刪除成功!!!\n");
206         PrintList(L);
207     }
208 }
209  
210 //查詢功能函式 呼叫LocateElem查詢元素
211 void Locate_Elem(SqList L)
212 {
213     ElemType e; int flag;
214     printf("請輸入要查詢的值:\n");
215     scanf("%d", &e);
216     flag = Locate_Elem(L, e);
217     if (flag)
218     {
219         printf("該元素位置為:%d\n", flag);
220     }
221     else
222         printf("未找到該元素!\n");
223 }
224  
225 //選單
226 void menu()
227 {
228     printf("********1.建立                        2.插入*********\n");
229     printf("********3.刪除                        4.查詢*********\n");
230       printf("********5.倒置                        6.分奇偶排序***\n");
231     printf("********7.輸出                        8.清空*********\n");
232     printf("********9.退出                              *********\n");
233 }
234 int main()
235 {
236     SqList L; int choice;
237     InitList(L);
238     while (1)
239     {
240         menu();
241         printf("請輸入選單序號:\n");
242         scanf("%d", &choice);
243          if (9 == choice) break;
244          switch (choice)
245         {
246          case 1:Create(L); break;
247         case 2:Insert(L); break;
248         case 3:Delete(L); break;
249         case 4:Search(L); break;
250         case 5:Reverse(L); break;
251         case 6:SplitSort(L); break;
252         case 7:PrintList(L); break;
253         case 8:ClearList(L); break;
254         default:printf("輸入錯誤!!!\n");
255         }
256     }
257     return 0;
258 }
259  

以上部分程式碼和圖片轉自以下兩篇文章,如有侵權,請告知刪除! 「lady_killer9」 《資料結構-順序表基本操作的實現(含全部程式碼)》
原文連結:https://blog.csdn.net/lady_killer9/article/details/82695770 「飯_團」 《順序表(一)》
原文連結:https://blog.csdn.net/f__yuan/article/details/97000573