C語言實現靜態順序表
阿新 • • 發佈:2018-12-05
實現順序表分為以下幾步:
1.先寫出封裝順序表結構的結構體;
2.初始化順序表;
3.增刪查改;
4.順序表的逆置等。
#define MAX_SIZE 100 typedef int DataType; typedef struct SeqList { DataType data[MAX_SIZE]; DataType length; }SeqList; //順序表的初始化就是把順序表初始化成空的順序表,再把順序表長度置0即可 void InitSeqList(SeqList *pList) { if(pList == NULL) { return ; } pList->length = 0; } //獲取順序表的長度,順序表元素個數即位順序表長度 int GetLengthSeqList(SeqList *pList) { assert(pList); return pList->length; } //查詢順序表中第i個元素,按順序查詢,判斷是否合法即可 int FindiSeqList(SeqList *pList, int i) { assert(pList); if(pList->length < 1 || pList->length > GetLengthSeqList(pList)) { return 0; } //因為陣列下標是從0開始的,而陣列元素是從1開始的。 return pList->data[i-1]; } //插入操作:在指定位置i插入一個元素,首先考慮順序表是不是已經滿了,插入位置合不合法, //其次,插入後,i之後所有元素都必須向後移動移位,必須得從最後一位開始移動,然後將i-1這個陣列下標的元素改為d,最後再將順序表長度+1。 int InsertSeqList(SeqList *pList, int i, DataType d) { int k = 0; assert(pList); if(pList->length < 1 || pList->length > GetLengthSeqList(pList)) { return 0; } else if(pList->length >= MAX_SIZE) { return 0; } else { //pList->length這裡求出來的是元素的個數,元素個數比陣列下標大1,正好就i之後所有元素向後移了一位 //這裡k=i-1很重要,因為順序表是從0開始的,如果不-1,我們就找不到i在順序表中正確的位置,以至於i在順序表中原本的那個值就無法給後面的元素 for(k = pList->length; k >= i-1; k--) { pList->data[k+1] = pList->data[k]; } pList->data[i-1] = d; pList->length++; return 1; } } //刪除操作:在指定位置i刪除一個元素d,需要將表中第i個元素之後的所有元素向前移位移位,再將順序表長度-1. void DeleteSeqList(SeqList *pList, int i) { assert(pList); if(pList->length < 1 || pList->length > GetLengthSeqList(pList)) { return ; } else { while(i < pList->length) { pList->data[i-1] = pList->data[i]; i++; } pList->length--; } } //按內容查詢:先找到這個元素,然後返回這個元素的下標+1即可 int GetLocateSeqList(SeqList *pList, DataType d) { int i = 0; assert(pList); for(i = 0; i <= pList->length; i++) { if(pList->data[i] == d) { return i+1; } } return 0; } //判斷順序表是否為滿順序表 int IsFullSeqList(SeqList *pList) { assert(pList); return (pList->length == MAX_SIZE); } //判斷順序表是否為空:如果順序表的長度為0,則順序表為空 int IsEmptySeqList(SeqList *pList) { assert(pList); if(pList->length == 0) { return 1; } return 0; } //尾插:先檢測順序表是否已滿,滿了就返回,未滿就可以插入,在順序表最後一個元素在接上一個元素,結束後給順序表長度+1. void PushBackSeqList(SeqList *pList, DataType d) { assert(pList); if(IsFullSeqList(pList)) { return ; } else { pList->data[pList->length] = d; pList->length++; } } //尾刪:先判斷順序表是不是為空,刪掉最後一個元素,然後順序表長度-1. void PopBackSeqList(SeqList *pList) { assert(pList); if(IsEmptySeqList(pList)) { return ; } else { pList->length--; } } //頭插:先判斷順序表是否為滿順序表,如果滿就返回,不滿就插入,相當於從第i個位置插入一個元素,只不過這個i位置為1. void PushFrontSeqList(SeqList *pList, DataType d) { int i = 0; assert(pList); if(IsFullSeqList(pList)) { return ; } else { for(i = pList->length; i >= 0; i--) { pList->data[i+1] = pList->data[i]; } pList->data[0] = d; pList->length++; } } //頭刪:先判斷順序表是否為空,如果不為空,從1位置處開始給前一位賦值。 void PopFrontSeqList(SeqList *pList) { int i = 0; assert(pList); if(IsEmptySeqList(pList)) { return ; } else { for(i = 0; i < pList->length; i++) { pList->data[i] = pList->data[i+1]; } pList->length--; } } //求順序表的大小 int SizeOfSeqList(SeqList *pList) { assert(pList); return (pList->length); } //清空順序表,因為不存在記憶體開闢,也不需要記憶體釋放,只需將順序表的長度置為0即可。 void ClearSeqList(SeqList *pList) { assert(pList); pList->length = 0; } void PrintSeqList(SeqList *pList) { int i; for(i = 0; i < pList->length; i++) { printf("%3d", pList->data[i]); } printf("\n"); } //氣泡排序 void BubbleSortSeqList(SeqList *pList) { int i = 0; int j = 0; assert(pList); //for(i = 0; i < pList->length-1; i++) //{ // for(j = 0; j < pList->length - i - 1; j++) // { // if(pList->data[j] < pList->data[j+1]) // { // int tmp = pList->data[j]; // pList->data[j] = pList->data[j+1]; // pList->data[j+1] = tmp; // } // } //} for(i = 0; i < pList->length-1; i++) { for(j = pList->length-2; j >= i; j--) { if(pList->data[j] < pList->data[j+1]) { int tmp = pList->data[j]; pList->data[j] = pList->data[j+1]; pList->data[j+1] = tmp; } } } } //選擇排序: void SelectSortSeqList(SeqList *pList) { int i, j, min; assert(pList); for(i = 0; i < pList->length-1; i++) { min = i; for(j = i+1; j < pList->length; j++) { if(pList->data[min] > pList->data[j]) { min = j; } } if(min != i) { int tmp = pList->data[i]; pList->data[i] = pList->data[min]; pList->data[min] = tmp; } } } //選擇排序優化:定義兩個指標,兩邊同時進行選擇,會比之前的版本快一半。 void SelectSortSeqList_OP(SeqList *pList) { int i = 0; int tmp; int left = 0; int right = pList->length-1; assert(pList); while(left < right && (left < pList->length && right >= 0)) { int min = left; int max = right; for(i = left; i <= right; i++) { if(pList->data[i] < pList->data[min]) min = i; if(pList->data[i] > pList->data[max]) max = i; } tmp = pList->data[max]; pList->data[max] = pList->data[right]; pList->data[right] = tmp; //特別注意這條判斷: //因為這是最極端的情況,最大值和最小值分別在最兩邊,當改變一邊的值之後,比如這個情況,min=5,max=0,但是max之前已經將0位置的值和right的值交換了, //而此時如果不判斷min的位置,因為right裡面的值已經改了,在用min去取right裡面的值已經不合理了,只能找被max剛才交換出去的值,才是正確的 if(min == right) min = max; tmp = pList->data[min]; pList->data[min] = pList->data[left]; pList->data[left] = tmp; left++; right--; } } //二分查詢 int BinarySearchSeqList(SeqList *pList, DataType d) { int left = 0; int right = pList->length-1; int mid = (pList->length-1)/2; assert(pList); while(left <= right) { if(d < pList->data[mid]) { right = mid - 1; mid = (left + right)/2; } else if(d > pList->data[mid]) { left = mid + 1; mid = (left + right)/2; } else return mid; } return -1; } //二分查詢遞迴實現 int BinarySearchSeqList_R(SeqList *pList, int left, int right, DataType d) { int mid = (left + right)/2; assert(pList); while(left <= right) { if(d < pList->data[mid]) right = mid - 1; else if(d > pList->data[mid]) left = mid + 1; else return mid; return BinarySearchSeqList_R(pList, left, right, d); } return -1; } //反轉順序表 void ReverseSeqList(SeqList *pList) { int left = 0; int right = pList->length-1; while(left < pList->length/2) { int tmp = pList->data[left]; pList->data[left] = pList->data[right]; pList->data[right] = tmp; left++; right--; } }