線性表(List)是零個或者多個數據元素的有限序列.算法
1ADT 線性表(List)
2Data
3 線性表的數據對象集合爲{a1, a2, a3, ......, an},每一個元素類型爲DataType。
4Operation
5 InitList(L); //初始化線性表
6 IsEmptyList(L); //判斷線性表是否爲空
7 ClearList(L); //清空線性表
8 GetElemList(L, i, *e); //獲取第i個位置的數據
9 SearchList(L, e); //查找與數據e相等的元素
10 InsertNodeList(L, i, e);//在第i個位置插入元素
11 DeleteNodeList(L, i, *e);//刪除第i個位置的元素,e獲取刪除元素
12 GetLengthList(L); //獲取線性表的長度
13endADT
關於線性表的基本操做就上面幾種,還有幾個例如線性表的排序,合併,逆序等等操做。爲了文章篇幅,就下次再介紹了。數組
線性表的順序存儲結構,就是指 用一段地址連續的存儲單元一次存儲線性表的數據元素。學太高級語言的朋友,相信對數組這玩意兒都不會陌生吧。數組就是一種順序存儲結構。微信
鏈式存儲結構就是能夠用一組任意的內存單元存儲線性表中的元素。與順序存儲不一樣的是,這組內存單元能夠是連續的,也能夠是不連續的。這就意味着,元素能夠存儲在內存的任意位置。正由於如此,在鏈式結構中,每一個元素不只要存它的信息,還須要存儲它後繼元素的存儲地址。咱們把存儲元素信息的域稱爲數據域,而把存儲後繼元素地址的域稱爲指針域。由這兩部分共同組成的數據元素ai,則能夠稱之爲節點(Node)。
以下面這個圖所示:app
鏈表就是鏈式存儲的線性表。結點之間經過邏輯鏈接,造成鏈式存儲結構。存儲結點的內存單元,能夠是連續的也能夠是不連續的。邏輯鏈接與物理存儲次序沒有關係。函數
採用順序存儲結構的線性表,就是順序表。測試
這裏咱們統一採用C語言來描述。spa
1#define MAXSIZE 20 //存儲空間的初始大小
2typedef int DataType //類型可根據實際狀況而定
3typedef struct
4{
5 DataType data[MAXSIZE]; //數組來存儲數據
6 int length; //實際長度
7}SqlList;
可見,順序表的幾個重要特性:指針
相信你們在排隊的時候都有過被插隊的體驗吧。當一個插隊到你前面時,這個時候你心裏os mmp外加素質三連的同時,也不得不日後挪一個位置。因而乎這個就不得了了,你後面的也要日後挪,你後面的後面也是……而後隊伍裏瞬間就狼煙起……
那麼,這個順序表的插入其實也差很少的。因爲地址是連續存儲的,那麼在某個地方插入之後,其後的元素不得不日後挪一個位置。code
插入算法描述:orm
因爲數組下標是從0開始的,咱們習慣要刪除的位置第i處又是從1開始算起的。本文就所有統一成,都從0開始吧。好比要在第5個位置插入一個元素,那就是a[5]。否則真的會混亂的。
具體代碼以下:
1//功能:在順序表L第i個位置以前插入元素e
2int InsertSqlList(SqlList *L, int i, DataType data)
3{
4 int k;
5 if(L->length==MAXSIZE || i<0 || i>L->length) //記住,都是從0開始的哦
6 return 0;//異常處理
7 if(i == L->length)
8 L->data[length++] = data;//尾插一步到位
9 if(i < L->length) //中間插,要挪人啦
10 {
11 for(k = L->length-1; k >= i;k--) //再次強調哈,都是從0開始的。
12 L->data[k+1]=L->data[k];//後移
13 L->data[i] = data;//新元素插入
14 L->length++;
15 }
16 return 1;
17}
算法描述:
1//功能:在順序表L中刪除第i個數據元素,用e獲取被刪除值
2int DeleteElemList(SqlList *L, int i, DataType *e)
3{
4 int k;
5 if(L->length==0 || i<0 || i>L->length-1) //記住,都是從0開始的哦
6 return 0;//異常處理
7 if(i == L->length-1) //尾刪,easy
8 {
9 *e = L->data[i];//獲取要刪除元素
10 L->length--; //刪除元素
11 }
12 if(i < L->length) //中間刪,要挪人啦
13 {
14 *e = L->data[i];//獲取要刪除元素
15 for(k = i; k < L->length-1;k++) //再次強調哈,都是從0開始的。
16 L->data[k]=L->data[k+1];//前移
17 L->length--;
18 return 1;
19 }
1#include <stdio.h>
2#include <stdlib.h>
3#define MAXSIZE 20
4#define ERROR 0
5#define OK 1
6#define NO 0
7#define YES 1
8
9typedef int DataType;
10typedef int Status;
11
12typedef struct List
13{
14 int data[MAXSIZE];
15 int length;
16}SqlList;
17
18void InitList(SqlList * L); //初始化順序表
19Status IsEmptyList(SqlList *L); //判斷順序表是否爲空
20void ClearList(SqlList *L); //清空線性表
21Status GetElemList(SqlList *L,int i,DataType *e); //獲取第i個位置的數據
22int SearchList(SqlList *L, DataType e); //查找與數據e相等的元素
23Status InsertNodeList(SqlList *L, int i,DataType e);//在第i個位置插入元素
24Status DeleteNodeList(SqlList *L, int i, DataType *e);//刪除第i個位置的元素,e獲取刪除元素
25int GetLengthList(SqlList *L); //獲取線性表的長度
26void PrintList(SqlList *L); //遍歷順序表,此函數測試使用,根據實際類型編寫
27
28int main()
29{
30 int e;
31 SqlList *pL = (SqlList*)malloc(sizeof(SqlList));
32 InitList(pL);
33 InsertNodeList(pL, 0, 1);
34 InsertNodeList(pL, 1, 2);
35 InsertNodeList(pL, 2, 3);
36 InsertNodeList(pL, 3, 4);
37 InsertNodeList(pL, 4, 5);
38 InsertNodeList(pL, 5, 6);
39
40 PrintList(pL);
41
42 DeleteNodeList(pL, 2, &e);
43 DeleteNodeList(pL, 4, &e);
44
45 PrintList(pL);
46
47
48 return 0;
49}
50
51void InitList(SqlList * L)
52{
53 for(int i = 0; i < MAXSIZE; i++)
54 L->data[i] = 0;
55 L->length = 0; //將表設爲空
56}
57
58Status IsEmptyList(SqlList *L)
59{
60 if(L->length == 0)
61 return YES;//表爲空
62 else
63 return NO;
64}
65
66void ClearList(SqlList *L)
67{
68 InitList(L);//此操做跟初始化同樣。
69}
70//這裏的第i個位置,爲了統一咱們也是從0算起的
71Status GetElemList(SqlList *L,int i,DataType *e)
72{
73 if(i < 0 || i >= L->length || L->length == 0)
74 return ERROR;//異常處理
75 *e = L->data[i];
76
77 return OK;
78}
79//找到與數據e相同的節點,返回下標。-1表示沒找到,ERROR表示表爲空
80int SearchList(SqlList *L, DataType e)
81{
82 if(L->length == 0)
83 return ERROR;
84 for(int i = 0; i < L->length; i++)
85 {
86 if(L->data[i] == e)
87 return i;
88 }
89
90 return -1;
91}
92//獲取順序表的長度
93int GetLengthList(SqlList *L)
94{
95 return L->length;
96}
97//在位置i插入元素,再次強調,從0開始
98Status InsertNodeList(SqlList *L, int i,DataType e)
99{
100 if(i < 0 || i > L->length || L->length == MAXSIZE)
101 return ERROR;//異常處理
102 for(int k = L->length; k > i; k--)
103 {
104 L->data[k] = L->data[k-1]; //日後挪
105 }
106 L->data[i] = e;//插入數據,
107 L->length++; //長度也要加1
108
109 return OK;
110}
111
112Status DeleteNodeList(SqlList *L, int i, DataType *e)
113{
114 if(i < 0 || i > L->length || L->length == 0)
115 return ERROR;//異常處理
116 *e = L->data[i];//獲取數據
117 for(int k = i; k < L->length -1; k++)
118 L->data[k] = L->data[k+1];//往前挪
119 L->length--; //長度減1
120 return OK;
121}
122
123void PrintList(SqlList *L)
124{
125 if(L->length == 0)
126 {
127 printf("順序表爲空\n");
128 }
129 printf("============遍歷順序表以下=============\n");
130 for(int i = 0; i < L->length; i++)
131 {
132 printf("\tdata[%d] = %d\n", i, L->data[i]);
133 }
134 printf("============共計%d個元素=============\n", L->length);
135
136}
簡單測試了一下。若是存在問題,歡迎指正,謝謝你們。