考研王道數據結構-順序表(綜合應用1)
阿新 • • 發佈:2018-06-02
typedef SQ src 動態分配 作用 測試 value com 順序表
本節代碼主要來自王道單科18頁的綜合應用題。
一、18頁第1題。從順序表中刪除具有最小值的元素(假設唯一)並由函數返回被刪元素的值。
空出的位置由最後一個元素填補,若順序表為空則顯示出錯信息並退出運行 。
核心代碼:
bool DeleteMinElem(Sqlist &L,ElemType &value){ // 18頁第1題。從順序表中刪除具有最小值的元素(假設唯一)並由函數返回被刪元素的值。 //空出的位置由最後一個元素填補,若順序表為空則顯示出錯信息並退出運行 if(L.length==0){ printf("順序表為空"); return0; } int pos=0; value=L.data[0]; for(int i=1;i<L.length;i++){ if(L.data[i]<value){ value=L.data[i]; pos=i; } } L.data[pos]=L.data[L.length-1]; L.length--; return 1; }
二、18頁第2題。設計一個高效的算法,將順序表的所有元素逆置,要求算法的空間復雜度為O(1)
核心代碼:
可以有兩種方式:
第一種:定義兩個循環指針i,j,其中i向後遍歷,j向前遍歷,這種更好記憶。
void Reverse(Sqlist &L){ int i,j; ElemType temp; for(i=0,j=L.length-1;i<j;i++,j--){ temp=L.data[i]; L.data[i]=L.data[j]; L.data[j]=temp; } }
第二種:j沒有定義出來,用i和L.length(即L.length-i-1)的關系來表示其對稱位置。
void Reverse2(Sqlist &L){int i; ElemType temp; for(i=0;i<L.length/2;i++){ temp=L.data[i]; L.data[i]=L.data[L.length-i-1]; L.data[L.length-i-1]=temp; } }
三、18頁第3題。刪除線性表中所有值為x的元素。要求時間復雜度O(n),空間復雜度O(1)。
核心代碼:
可以有三種方式:
第一種:遍歷時統計等於x的個數count,將不等於x的元素向前移動count個位置。
void DeleteElemX1(Sqlist &L,ElemType x){ int count=0;//計算元素等於x的個數 for(int i=0;i<L.length;i++){ if(L.data[i]==x) count++; else L.data[i-count]=L.data[i]; } L.length-=count; }
第二種:把不等於x的元素重新覆蓋,個數為count。
此處count起到了統計不等於x的個數(即剩余元素的個數),也起到了覆蓋元素時的遍歷作用。
void DeleteElemX2(Sqlist &L,ElemType x){ int count=0;//這次是計算不等於x的個數 for(int i=0;i<L.length;i++){ if(L.data[i]!=x){ L.data[count]=L.data[i]; count++; //註意這一句要在後面,因為覆蓋元素位置從0開始。 } } L.length=count; //這句不要忘了。 }
第三種:用頭尾兩個指針i,j從兩端向中間移動,凡遇到左端值x的元素時,直接將最右端值非x的元素左移至值為x的數據元素位置,直到兩指針相遇。
但這種方法會改變原表元素的相對位置。不推薦。就暫時不寫了。
以下是以上三道題的全部測試代碼(可直接運行):
#include<stdio.h> #define true 1 #define false 0 #define MaxSize 100 //定義線性表的最大長度 #define ElemType int #define Status int typedef struct{ ElemType data[MaxSize]; //動態分配數組的指針 int length; //當前個數 }Sqlist; //構造一個空的線性表L void InitList(Sqlist &L){ L.length=0; } bool ListInsert(Sqlist &L,int i,ElemType e){ //將元素e插到順序表L中第i個位置 if(i<1||i>L.length+1) return false; if(L.length>=MaxSize) return false; for(int j=L.length;j>=i;j--) L.data[j]=L.data[j-1]; L.data[i-1]=e; L.length++; return true; } void ListLoad(Sqlist L){ if(L.length==0){ printf("當前順序表為空\n"); return; } printf("當前順序表元素為:"); for(int i=0;i<L.length;i++) printf("%d ",L.data[i]); printf("\n"); return; } // 18頁第1題。從順序表中刪除具有最小值的元素(假設唯一)並由函數返回被刪元素的值。 //空出的位置由最後一個元素填補,若順序表為空則顯示出錯信息並退出運行 bool DeleteMinElem(Sqlist &L,ElemType &value){ if(L.length==0){ printf("順序表為空"); return 0; } int pos=0; value=L.data[0]; for(int i=1;i<L.length;i++){ if(L.data[i]<value){ value=L.data[i]; pos=i; } } L.data[pos]=L.data[L.length-1]; L.length--; return 1; } void Reverse1(Sqlist &L){ //18頁第2題。設計一個高效的算法,將順序表的所有元素逆置,要求算法的空間復雜度為O(1) int i,j; ElemType temp; for(i=0,j=L.length-1;i<j;i++,j--){ temp=L.data[i]; L.data[i]=L.data[j]; L.data[j]=temp; } } void Reverse2(Sqlist &L){ //18頁第2題。設計一個高效的算法,將順序表的所有元素逆置,要求算法的空間復雜度為O(1) int i; ElemType temp; for(i=0;i<L.length/2;i++){ temp=L.data[i]; L.data[i]=L.data[L.length-i-1]; L.data[L.length-i-1]=temp; } } //遍歷時統計等於x的個數count,將不等於x的元素向前移動count個位置。 void DeleteElemX1(Sqlist &L,ElemType x){ int count=0;//計算元素等於x的個數 for(int i=0;i<L.length;i++){ if(L.data[i]==x) count++; else L.data[i-count]=L.data[i]; } L.length-=count; } //把不等於x的元素重新覆蓋,個數為count。 //此處count起到了統計不等於x的個數(即剩余元素的個數),也起到了覆蓋元素時的遍歷作用。 void DeleteElemX2(Sqlist &L,ElemType x){ int count=0;//這次是計算不等於x的個數 for(int i=0;i<L.length;i++){ if(L.data[i]!=x){ L.data[count]=L.data[i]; count++; //註意這一句要在後面,因為覆蓋元素位置從0開始。 } } L.length=count; //這句不要忘了。 } int main(){ Sqlist T; ElemType min; ElemType e; int a; InitList(T); ListInsert(T,1,4); ListInsert(T,1,3); ListInsert(T,1,6); ListInsert(T,2,1); ListInsert(T,2,8); ListInsert(T,2,8); ListInsert(T,2,9); ListLoad(T); while(1){ printf("1:刪除最小元素\n"); //DeleteMinElem printf("2:所有元素逆置(方法1)\n"); //Reverse1 printf("3:所有元素逆置(方法2)\n"); //Reverse2 printf("4:刪除值等於x的所有元素(方法1)\n"); //DeleteElemX1 printf("5:刪除值等於x的所有元素(方法2)\n"); //DeleteElemX2 printf("請選擇:"); scanf("%d",&a); switch(a){ case 1:if(DeleteMinElem(T,min)) printf("成功刪除最小元素%d\n",min); else printf("刪除失敗\n"); break; case 2:Reverse1(T); break; case 3:Reverse2(T); break; case 4:scanf("%d",&e); DeleteElemX1(T,e); break; case 5:scanf("%d",&e); DeleteElemX2(T,e); break; default:return 1; } ListLoad(T); } }
刪除最小元素:
順序表逆置:
刪除值等於x的所有元素:
考研王道數據結構-順序表(綜合應用1)