線性表是一種隨機存取的結構,和鏈表不同,鏈表順序存取的結構。但是,線性表是一種順序存儲的結構,而鏈表是鏈式存儲結構。兩者都是線性的,但區別不同。
進入主題:
1.假如有一串數據元素,要求刪除其中的重復元素。
首先想到的是用兩層循環,第一層從第一個元素開始,第二層從第一層元素的下一個元素開始。
就是假如第一層是ai元素,則第二層就為ai+1元素。
函數實現:
1 void Purge1(ElemType A[],int &n){//ElemType表示任意數據類型,以后不再說明//n為線性表的長度 2 int i=0,j; 3 while(i<n){ 4 j=i+1; 5 while(j<n){ 6 if(A[j]==A[i]) 7 Deletelist(A,n,j+1);//具體函數實現最后給出 8 else 9 j++; 10 } 11 i++; 12 } 13 }
2.如果這些元素是按遞增排列,且數據量很大的話,使用上面的算法就會造成時間上的浪費。
那要怎么優化呢?
具體想法就是用一個變量k記錄重復的個數,然后第i個元素和第i+1個元素進行比較,若相等,則k自增。否則第i+1個元素的值賦值給第i-k+1個元素的值。當k=0時,其實就是自己賦值給自己。
舉個例子:
1 2 2 3 4 6 6 6 8 9
i從第1個元素開始,到第2個元素時,此時第2個元素和第3個元素相等,執行k++。然后進行下一次循環,第3個元素不等於第4個元素,因為此時k=1,故第3個元素被賦予第4個元素的值3。然后直到第6個元素,此時又相等,k=2。第7個也相等,k=3。然后到第8個元素,第6個元素被賦予值8,就是第9個元素的值。然后最后一個元素9。此時表的長度為n=10-k=7。
函數實現:
1 void Purge2(int *A, int &n) { 2 int i = 0, k = 0;//k是重復的次數或是要刪除的數的個數 3 for (i = 0; i < n - 1; i++) 4 if (A[i] != A[i + 1]) 5 A[i-k+1] = A[i + 1]; 6 else 7 k++; 8 n = n - k; 9 }
經過小規模的測試沒有發現問題。
經過兩函數的分析,可以看出第一個函數使用的是兩層循環,而第二個函數只使用了一層循環達到了效果。
避免了不必要的時間浪費。
附上Deletelist函數:
1 void Deletelist(int *A, int &n, int i) { 2 int j; 3 if (i<1 || i>n)//這條可以無視 4 cout << "超出范圍!"; 5 for (j = i; j < n; j++) 6 A[j - 1] = A[j]; 7 n--; 8 }
碎碎念:本人是個大二學生,興趣就是寫代碼,通過寫代碼來解決算法題,以此來獲得成就感。目前感興趣的方向是網絡安全。我也喜歡在閑余時間玩玩游戲,看看資料。
