日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构学习笔记(六)链表算法题

發布時間:2025/3/8 编程问答 13 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构学习笔记(六)链表算法题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

假期結束,看點題目。

第一題

問題

設順序表用數組A[]表示,表中元素存儲在數組下標1~m+n的范圍內,前m個元素遞增有序,后n個元素遞增有序,設計一個算法,使得整個順序表有序。
(1)給出算法的基本設計思想。
(2)根據設計思想,采用C或C++語言描述算法,關鍵之處給出注釋。
(3)說明你所設計算法的時間復雜度和空間復雜度。

解答

(1)算法基本設計思想:
將數組A[]中的m+n個元素(假設元素為int型)看成兩個順序表,表L和表R。將數組當前狀態看做起始狀態,即此時表L由A[]中前m個元素構成,表R由A[]中后n個元素構成。要使A[]中m+n個元素整體有序只需將表R中的元素逐個插入表L中的合適位置即可。插入過程:取表
R中的第一個元素A[m+1]存入輔助變量temp中,讓temp逐個與A[m],A[m-1],…,A[1]進行比較,當temp<A[j](1≤j≤m)時,將A[j]后移一位;否則將temp存入A[j+1]中。重復上述過程繼續插入A[m+2],A[m+3],……,A[m+n],最終A[]中元素整體有序。

(2)算法描述

void Insert(int A[],int m,int n){int i,j;int temp; //輔助變量,用來暫存待插入元素。for(i=m+1;i<=m+n;i++) { //將A[m+1…m+n]插入到A[1…m]中。temp=A[i];for(j=i-1;j>=1&&temp<A[j];j--)A[j+1]=A[j]; //元素后移,以便騰出一個位置插入temp。A[j+1]=temp; //在j+1位置插入temp。} }

(3)算法時間和空間復雜度
①本題的規模由m和n共同決定。取最內側循環中A[j+1]=A[j];這一句作為基本操作,其執行次數在最壞的情況下為:f(m,n)=(m+m+n-1)n/2=mn+n2/2–n/22
②算法額外空間中只有一個變量temp,因此空間復雜度為O(1)。

第二題

問題

已知遞增有序的單鏈表A,B(A,B中元素個數分別為m,n且A,B都帶有頭結點)分別存儲了一個集合,請設計算法以求出兩個集合A和B的差集A-B(即僅由在A中出現而不在B中出現的元素所構成的集合)。將差集保存在單鏈表A中,并保持元素的遞增有序性。

(1)給出算法的基本設計思想。
(2)根據設計思想,采用C或C++語言描述算法,關鍵之處給出注釋。
(3)說明你所設計算法的時間復雜度。

解答

(1)算法基本設計思想:
只需從A中刪去A與B中共有的元素即可。由于兩個鏈表中元素是遞增有序的所以可以這么做:設置兩個指針p, q開始時分別指向A和B的開始結點。循環進行以下判斷和操作,如果p所指結點的值小于q所指結點值,則p后移一位;如果q所指結點的值小于p所指結點的值,則q后移一位;如果兩者所指結點的值相同,則刪除p所指結點。最后p與q任一指針為NULL的時候算法結束。

(2)算法描述:

void Difference(LNode *&A, LNode *B) {LNode *p = A->next, *q = B->next; //p和q分別是鏈表A和B的工作指針。LNode *pre = A;LNode *r;while(p != NULL && q != NULL) {if(p->data < q->data) {pre = p; //pre 為A中p所指結點的前驅結點的指針。p = p->next; //A鏈表中當前結點指針后移。}else if (p->data > q->data)q = q->next;else {pre->next = p->next; //B 鏈表中當前結點指針后移。r = p; //處理A,B中元素值相同的結點,應刪除。p = p->next;free(r); // 刪除結點。}} }

(3)算法時間復雜度分析:
由算法描述可知,算法規模由m和n共同確定。算法中有一個單層循環,循環內的所有操作都是常數級的,因此可以用循環執行的次數作為基本操作執行的次數。可見循環執行的次數即為p, q兩指針沿著各自鏈表移動的次數,考慮最壞的情況,即p, q都走完了自己所在的鏈表,循環執行m+n次。即時間復雜度為O(m+n)。

第三題

問題

設計一個算法,將順序表中的所有元素逆置。

解答

兩個變量i,j指示順序表的第一個元素和最后一個元素,交換i,j所指元素,然后i向后移動一個位置,j向前移動一個位置,如此循環,直到i與j相遇時結束,此時順序表L中的元素已經逆置。

void reverse(Sqlist &L) { //L要改變,用引用型int i,j;int temp; //輔助變量,用于交換for(i=1,j=L.length;i<j;i++,j--) { //當i與j相遇時循環結束temp=L.data[i];L.data[i]=L.data[j];L.data[j]=temp;} }

注意:本題中 for 循環的執行條件要寫成i < j 而不要寫成i != j 。如果數組中元素有偶數個則 i 與 j 會出現下圖所示狀態,此時i 繼續往右走,j 繼續往左走,會互相跨越對方,循環不會結束。

第四題

問題

設計一個算法,從一給定的順序表L中刪除下標i到j(i≤j,包括i,j)之間的所有元素,假定i,j都是合法的。

解答

本題是順序表刪除算法的擴展,可以采用如下方法解決,從第j+1個元素開始到最后一個元素為止,用這之間的每個元素去覆蓋從這個元素開始往前數第j-i+1個元素,即可完成刪除i~j之間的所有元素。

本題代碼如下:

void Delete(Sqlist &L,int i,int j) { //L要改變,用引用型。int k,l;l = j-i+1; //元素要移動的距離。for(k = j + 1;k <= L.length; k++) {L.data[k-l] = L.data[k]; //用第k個元素去覆蓋它前邊的第l個元素。}L.length -= l; //表長改變。 }

第五題

問題

有一個順序表L,其元素為整型數據,設計一個算法,將L中所有小于表頭元素的整數放在前半部分,大于的整數放在后半部分,數組從下表1開始存儲。

解答

本題可以這樣解決,先將L的第一個元素存于變量temp中,然后定義兩個整型變量i,j。i從左往右掃描,j從右往左掃描。邊掃描邊交換。具體執行過程如下:

各步的解釋如下:
①開始狀態,temp = 2,i = 1; j = L.length
②j先移動,從右往左,邊移動邊檢查j所指元素是否比2小,此時發現-1比2小,則執行L.data[i]=L.data[j];i++;(i中元素已經被存入temp所以可以直接覆蓋,并且i后移一位,準備開始i的掃描)
③i開始移動,從左往右,邊移動邊檢測,看是否i所指元素比2大,此時發現-7比2小,因此i在此位置是什么都不做。
④i繼續往右移動,此時i所指元素為-3也比2小,此時什么都不做。
⑤i繼續往右移動,此時i所指元素為5,比2大,因此執行L.data[j] = L.data[i]; j--(j中元素已被保存,j前移一位,準備開始j的掃描)
⑥j往左運動,此時j所指元素為6,比2大,j在此位置時,什么都不做。
⑦j繼續往左移動,此時j==i,說明掃描結束。
⑧執行L.data[i] = temp;此時整個過程結束,所有比2小的元素被移到了2前邊,所有比2大的元素被移到了2后邊。

以上過程要搞清楚兩點:
①i和j是輪流移動的,即當i找到比2大的元素時,將i所指元素放入j所指位置,i停在當前位置不,j開始移動。j找到比2小的元素,將j所指元素放在i所指位置,j停在當前位置不動,i開始移動如此交替直到i==j。
②每次元素覆蓋(比如執行L.data[i] = L.data[j];)不會造成元素丟失,因為在這之前被覆蓋位置的元素已經存入其他位置。由以上分析可寫出如下算法:

void move(Sqlist &L) { //L要改變所以用引用型int temp;int i = 1,j = L.length;temp = L.data[i];while(i<j){/*關鍵步驟開始*/while(i < j&&L.data[j] > temp) j--; //j從左往右掃描,當來到第一個比temp小的元素時停止 ,并且每走一步都要判斷i是否小于j,這個判斷容易遺漏。if(i < j) { //檢測看是否已仍滿足i < j,這一步同樣很重要L.data[i] = L.data[j]; //移動元素。i++; //i右移一位。}while(i < j&&L.data[i] < temp) i++; //與上邊的處理類似。if(i < j) { //與上邊的處理類似。L.data[j] = L.data[i]; //與上邊的處理類似。j--;}/*關鍵步驟結束*/}L.data[i] = temp; //將表首元素放在最終位置。 }

總結

以上是生活随笔為你收集整理的数据结构学习笔记(六)链表算法题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。