一個簡單的順序表基礎操作示例,順序基礎示例
最近學計算機軟件基礎,學到了線性表。下面就將線性表中最簡單的順序表的一個簡單示例貼出,方便大家探討。(以及後面對函數傳參的一個小分析,其實這才是重點)

![]()
1 ////需求分析
2 //1、線性表遞增有序,刪除重復元素
3 //2、線性表逆置
4 //3、尋求最大值
5
6 #include<stdio.h>
7
8 typedef int ElementType;
9 typedef struct _struct
10 {
11 ElementType SequenceList[100];
12 ElementType num;
13 }SequenceList;
14
15 void InitSeq(SequenceList **L);//初始化線性表,主要是返回一個SequenceList實例,采用malloc動態開辟內存方式。
16 int Add(SequenceList *L, ElementType value);//想列表中添加項目
17 void Insert(SequenceList *L ,ElementType pos, ElementType value);//插入一個元素
18 void Delete(SequenceList *L, ElementType value);//刪除一個元素
19 ElementType Search(SequenceList *L, ElementType value);//搜索一個元素
20 void RemoveRepetiton(SequenceList *L);//移除所有重復的元素
21 void Transpose(SequenceList *L);//將所有元素位置倒置
22 ElementType MaxValue(SequenceList *L);//求出元素中最大值
23 void Travel(SequenceList *L);//遍歷整個列表(把每個元素都輸出一遍)
24
25 int main()
26 {
27 SequenceList *L;
28 InitSeq(&L);
29 while (1)
30 {
31 int n = 0;
32 int pos;
33 ElementType value;
34 printf("請選擇操作:(1.Add 2.insert 3.delete 4.search 5.transpose 6.maxium 7.travel 8.removeReptitons)\n");
35 scanf("%d", &n);
36 switch (n)
37 {
38 //add
39 case 1:
40
41 printf("添加新項:");
42 scanf("%d", &value);
43 Add(L, value);
44 break;
45 //insert
46 case 2:
47
48 printf("選擇位置插入一項:(位置 值)\n");
49 scanf("%d %d", &pos,&value);
50 Insert(L,pos, value);
51 break;
52 //delete:
53 case 3:
54 printf("輸入刪除內容:");
55 scanf("%d", &value);
56 Delete(L, value);
57 break;
58 //Search
59 case 4:
60 printf("搜索內容:");
61 scanf("%d", &value);
62 pos = Search(L, value);
63 if (pos)
64 printf("存在於第%d項。\n", pos);
65 else
66 printf("無法找到!\n");
67 break;
68 //transpose:
69 case 5:
70 Transpose(L);
71 Travel(L);
72 break;
73 //max
74 case 6:
75 printf("最大值是%d。\n", MaxValue(L));
76 break;
77 case 7:
78 Travel(L);
79 break;
80 case 8:
81 RemoveRepetiton(L);
82 break;
83 default:
84 break;
85 }
86 }
87 free(L);
88 return 0;
89 }
90 void InitSeq(SequenceList **L)
91 {
92 *L = (SequenceList *)malloc(sizeof(SequenceList));
93 (*L)->num = -1;
94 }
95
96 int Add(SequenceList *L, ElementType value)
97 {
98 L->num++;
99 if (L->num >= 100)
100 {
101 L->num--;
102 printf("空間已滿!");
103 return 0;
104 }
105 L->SequenceList[L->num] = value;
106 return 1;
107 }
108
109 void Insert(SequenceList *L, ElementType pos, ElementType value)
110 {
111 if (L->num<0||L->num >= 99)
112 {
113 printf("空間已滿或不足!");
114 return 0;
115 }
116 if (pos-1 < 0 || pos-1 > L->num)
117 {
118 printf("插入位置錯誤!");
119 return;
120 }
121 int i;
122 for (i = L->num; i >= pos-1; i--)
123 {
124 L->SequenceList[i+1] = L->SequenceList[i];
125 }
126 L->SequenceList[pos - 1] = value;
127 L->num++;
128 }
129
130 void Delete(SequenceList *L, ElementType value)
131 {
132 if (L->num < 0)
133 {
134 printf("表為空!");
135 return;
136 }
137 int i;
138 for (i = 0; i <= L->num; i++)
139 {
140 if (value == L->SequenceList[i])
141 {
142 int j;
143 for (j = i; j < L->num; j++)
144 {
145 L->SequenceList[j] = L->SequenceList[j + 1];
146 }
147 L->num--;
148 }
149 }
150 }
151
152 ElementType Search(SequenceList *L, ElementType value)
153 {
154 if (L->num<0)
155 {
156 printf("表空!");
157 return -1;
158
159 }
160 else
161 {
162 int i;
163 for (i = 0; i <= L->num; i++)
164 {
165 if (value == L->SequenceList[i])
166 return i + 1;
167 }
168 }
169
170 return 0;
171 }
172
173 void RemoveRepetiton(SequenceList *L)
174 {
175 int count=0;
176 int i;
177 for (i = 0; i <= L->num; i++)
178 {
179 if (Search(L, L->SequenceList[i]))
180 {
181 Delete(L, L->SequenceList[i]);
182 count++;
183 }
184 }
185 printf("共刪除了%d項。", count);
186 }
187
188 void Transpose(SequenceList *L)
189 {
190 ElementType *temp = (ElementType *)malloc(sizeof(ElementType)*(L->num + 1));
191 int i ,j;
192 for (i = L->num, j = 0; i >= 0; i--,j++)
193 {
194 temp[j] = L->SequenceList[i];
195 }
196 for (i = 0; i <= L->num; i++)
197 {
198 L->SequenceList[i] = temp[i];
199 }
200 free(temp);
201 }
202 ElementType MaxValue(SequenceList *L)
203 {
204 int i = 0;
205 ElementType max = L->SequenceList[0];
206 for (i = 1; i <= L->num; i++)
207 {
208 if (max < L->SequenceList[i])
209 {
210 max = L->SequenceList[i];
211 }
212 }
213 return max;
214 }
215
216 void Travel(SequenceList *L)
217 {
218 if (L->num < 0)
219 printf("表空!");
220 else
221 {
222 int i;
223 for (i = 0; i <= L->num; i++)
224 {
225 printf("%d ", L->SequenceList[i]);
226 if (i>0&&(i % 10 == 0))
227 printf("\n");
228 }
229 printf("\n");
230 }
231 }
點擊查看代碼
代碼純手打,不是網上copy過來的。。
代碼中沒什麼算法,搜索、刪除等都用的最簡單的方式。
代碼中唯一值得注意的就是初始化列表的函數InitList(SequenceList **L),傳的是二級指針做參數,為什麼這麼做呢?
下面解釋一下:
我們的目的是在函數InitList中malloc一塊內存空間,用於存放我們的數據。
現在先看我們常寫的一個錯誤寫法
//請看如下錯誤代碼,這是為說明問題的錯誤代碼
void InitList(SequenceList *L)
{
L=(SequenceList *)malloc(sizeof(SequenceList));//語法重點。。
L->num=-1;//這個是程序功能的一部分
}
許多的初學者認為我們傳到函數InitList中的是一個指針變量,在InitList中可以對該指針變量進行賦值操作,以便達到修改主函數中變量的目的,於是乎便將malloc開辟的空間首地址賦給L,然後在主函數中對L操作的時候發現要麼是亂碼,要麼是不可訪問之類的錯誤,百思不得其解,為什麼呢?
原因很簡單,就是對函數參數的傳遞方式不明確造成的。在此處應該記著,函數傳參始終是將你所傳變量復制後的副本傳進去,並不是該變量本身。
代入這個實際問題,我們在主函數中做如下操作
//為錯誤情況的示例代碼,切記
void main()
{
SequenceList *L;
InitList(L);
......
}
我們為函數InitList傳遞的是一個SequenceList類型的指針變量L,假設L此時指向內存0x10000,則在實際傳參數的時候,系統會對L變量作一個復制操作,假設這兒使復制後的變量為P,則P指向的地址也為L指向的地址0x10000。
現在重點來了,我們為InitList傳遞參數L,但系統實際傳遞的參數是P(P是L的副本,他們指向同一塊內存區域,但他們各自的地址不同),在函數InitList內部,則實際是對P變量進行操作,把malloc的地址(假設為0x30000)賦值給P,
所以P指向的地址是0x30000,但是主函數中的L仍然指向0x10000,所以就造成了我們遇見的錯誤,因為我們根本沒有把L指向的地址改為malloc的地址;
那麼接下來看正確的操作。
//以下代碼為正確代碼
void main()
{
SequenceList *L;
InitList(&L);
}
void InitSeq(SequenceList **L)
{
*L = (SequenceList *)malloc(sizeof(SequenceList));
(*L)->num = -1;
}
我們傳參數的時候傳的是變量L的地址,那麼系統實際傳的是變量P,P與L有如下關系:P=&L(P指向變量L的地址).在函數InitList中
*L = (SequenceList *)malloc(sizeof(SequenceList));
L是P,*L即是主函數中的L,現在用malloc的地址給*L,就實現了為主函數中L賦值的操作。
明白了嗎?這是我個人的理解。可能系統在某些細節上和我說的不一樣,但我這個思路應該是沒錯的。