一.基本運算的實現
1.建立順序表
void CreateList(SqList * & L,ElemType a[],int n) //由a中的n個元素建立順序表 { int i = 0,k = 0; //k表示L中的元素個數,初始值為0 L = (SqList *)malloc(sizeof(SqList)); //分配線性表的空間 while(i < n) { L->data[k] = a[i]; //將元素a[i]存放到L中 k++; i++; } L->length = k; //設置L的長度K }
/* malloc(sizeof(數據類型))
功能:分配存儲空間
返回值:所分配的內存區地址 */
2.初始化線性表
void InitList(SqList * & L) { L = (SqList * )mallc(sizeof(SqList); //分配存放線性表的空間 L -> lenght = 0; }
/* 1.&代表引用型指針,類似於地址共享。需要對主函數的值進行修改時,就要用&引用。
2.(SqList *)為強制轉換,強制malloc分配為SqList的空間大小。 */
3.銷毀線性表
void DestroyList(SqList * & L) { free(L); //釋放L所指的順序表空間 }
// 若不進行銷毀,盡管系統會自動釋放順序表指針變量L,但不會自動釋放L所指向的存儲空間,如此可能會造成內存泄漏。
4.判斷線性表是否為空表
bool ListEmpty(SqList * L) { return(L -> length == 0); }
// 這里的“空”指空閑,不等於空白。只要L -> length == 0即為空表,不管表中是否有數據。
5.求線性表的長度
int ListLength(SqList * L) { return(L -> length); }
6.輸出線性表
void DispList(SqList * L) { int i = 0; for(i=0;i<L -> length;i++) printf("%d ",L -> data[i]); printf("\n"); }
7.求線性表中的第i個元素的值
bool GetElem(SqList * L,int i,ElemType &e) { if(i<1 || i>L -> length) return false; e = L -> data[i-1]; return true; }
8.查找第一個與e相等的元素
int LocateElem(SqList * L,ElemType e) { int i = 0; while(i<L -> length && L -> data[i]!=e) i++; if(i>=L -> length) return 0; else return i+1; }
9.在第i個位置上插入新數據
void ListInsert(SqList * & L,int i,ElemType e) { int j; if(i<1 || i>L -> length+1) return false; i--; for(j=L -> length;j>i;j--) L -> data[j] = L ->data[j-1]; L -> data[i] = e; L -> length++; return true; }
10.刪除第i個數據元素
bool ListDelete(SqList * & L,int i,ElemType &e) { int j; if(i<1 || i>L -> length) return false; i--; e = L -> data[i]; for(j=i;j<L -> length-1;j++) L -> data[j] = L -> data[j+1]; L -> length--; return true; }
二.應用示例
1.假設一個線性表采用順序表表示,設計一個算法,刪除其中所有制等於x的元素。要求算法的時間復雜度為O(n),空間復雜度為O(1).
//解法一 void delnode1(SqList * & L,ElemType x) { int k=0,i; //k記錄不等於x的元素個數,即要插入到L中的元素個數 for(i=0;i<L -> length;i++) if(L -> data[i] != x) //若當前元素不為x,將其插入到L中 { L -> data[k] = L -> data[i]; k++; } L -> length = k; } //解法二 void delnode2(SqList * & L,ElemType x) { int k=0,i=0; //k記錄等於x的元素個數 while(i<L -> length) { if(L -> data[i]==x) //當前元素為x時k增1 k++; else //當前元素不為x時將其前移k個位置 L -> data[i-k] = L-> data[i]; i++; } L -> length -= k; }
2.有一個順序表L,假設元素類型ElemType為整型,設計一個盡可能高效的算法,以第一個元素為分界線(基准),將所有小於等於它的元素一道該基准的前面,將所有大於它的元素移到該基准的后面。
//解法一 int partiton1(SqList * & L) { int i=0,j=L->length-1; //以data[0]為基准 ElemType pivot = L->data[0]; while(i < j) //從區間兩端交替向中間掃描,直到i=j為止 { while(i<j && L->data[j]>pivot) //從右向左掃描,找一個小於等於pivot的元素 j--; while(i<j && L->data[i]<=pivot) //從左向右掃描,找一個大於pivot的元素 i++; if(i < j) swap(L->data[i],L->data[j]); } swap(L->data[0],L->data[i]); } //解法二 void partition2(SqList * & L) { int i=0,j=L->length-1; ElemType pivot = L->data[0]; //以data[0]為基准 while(i < j) //從區間兩端交替向中間掃描,直到i=j為止 { while(i<j && L->data[j]>pivot) j--; //從右向左掃描,找一個小於等於pivot的data[j] L->data[i] = L->data[j]; //找到這樣的data[j],放入data[i]處 while(i<j && L->data[i]<=pivot) i++; //從左向右掃描,找一個大於pivot的data[i] L->data[j] = L->data[i]; //找到這樣的data[i],放入data[j]處 } L->data[i] = pivot; }
3.有一個順序表L,假設元素類型ElemType為整型,設計一個盡可能高效的算法,將所有奇數移動到偶數的前面。
//解法一 void move1(SqList * & L) { int i=0,j=L->length-1; while(i < j) { while(i<j && L->data[j]%2==0) j--; //從右向左掃描,找一個奇數元素 while(i<j && L->data[i]%2==1) i++; //從左向右掃描,找一個偶數 if(i < j) swap(L->data[i],L->data[j]); } } //解法二 void move2(SqList * & L) { int i=-1,j; for(j=0;j<=L->length-1;j++) if(L->data[j]%2 == 1) { i++; //奇數區間個數增1 if(i != j) swap(L->data[i],L->data[j]); } }