【資料結構與演算法】線性表——刪除重複元素
阿新 • • 發佈:2018-12-01
線性表是一種隨機存取的結構,和連結串列不同,連結串列順序存取的結構。但是,線性表是一種順序儲存的結構,而連結串列是鏈式儲存結構。兩者都是線性的,但區別不同。
進入主題:
1.假如有一串資料元素,要求刪除其中的重複元素。
首先想到的是用兩層迴圈,第一層從第一個元素開始,第二層從第一層元素的下一個元素開始。
就是假如第一層是ai元素,則第二層就為ai+1元素。
函式實現:
void Purge1(ElemType A[],int &n){//ElemType表示任意資料型別,以後不再說明//n為線性表的長度 int i=0,j; while(i<n){ j=i+1; while(j<n){ if(A[j]==A[i]) Deletelist(A,n,j+1);//具體函式實現最後給出 else j++; } i++; } }
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。
函式實現:
void Purge2(int *A, int &n) {
int i = 0, k = 0;//k是重複的次數或是要刪除的數的個數
for (i = 0; i < n - 1; i++)
if (A[i] != A[i + 1])
A[i-k+1] = A[i + 1];
else
k++;
n = n - k;
}
經過小規模的測試沒有發現問題。
經過兩函式的分析,可以看出第一個函式使用的是兩層迴圈,而第二個函式只使用了一層迴圈達到了效果。
避免了不必要的時間浪費。
附上Deletelist函式:
void Deletelist(int *A, int &n, int i) {
int j;
if (i<1 || i>n)//這條可以無視
cout << "超出範圍!";
for (j = i; j < n; j++)
A[j - 1] = A[j];
n--;
}
溜了,溜了。。。