(1) 首先鏈表我上學期已有必定的基礎,因此學起來沒有太大的困難,可是解決問題時不夠老道, 沒有寫出的代碼時間複雜度不是太好,和老師舉例的算法有明顯差距,這方面還需多積累。 (2) 其次鏈表操做會涉及到指針,指針的用法又能夠至關巧妙,讓原本複雜的問題變簡單, 可是用很差可能會留下各類小bug,難以查找,甚至崩潰。因此要多多領悟總結。
實如今順序表中刪除某個區間數據。須要實現下述的三個函數完成該功能。 實現函數: CreateSqList:建立有序表,連續輸入n個正數存入有序表中。L表示順序表指針,n表示輸入數據個數。 InsertSq(SqList *&L,int x):順序表L中插入數據x。 DispSqList:輸出順序表L中全部數據。數據間空格隔開,尾部不能有空格。
用new分配內存給L L->length賦值爲n,n爲輸入數據長度 if (n小於等於最大值50) then { 輸出「大於數組長度」 } end if if (n等於0) then { 輸出 "error" 而且退出 } else if (n大於0) then { for (i 從0開始循環到 L->length-1) { 輸入數據到 L->data[i]中 } } else 若是n<0爲不合法 { 輸出 "小於0 error" } end if
定義變量flag記錄插入位置 for (i 從 1 循環到 L->length=1 ) { if (L->data[0] 大於 x) then //插入頭 { 把標記flag = 0意爲插入頭 退出循環 } else if ( L->data[L->length - 1] 小於 x) 說明要插入尾 { 把標記flag = L->length - 1意爲插入尾 退出循環 } else if L->data[i] 大於x而且L->data[i - 1] 小於x then { 找到中間插入點賦給flag flag = i } end if } end for if (flag 等於 L->length - 1) then { L->data[L->length] = x //在尾部插入x } else { for (i = L->length to flag) { L->data[i] = L->data[i - 1] //後移 } end for L->data[flag] = x //插入x } end if 長度L->length加1
for (從i = 0 循環到 L->length) { 輸出 L->data[i] if i 小於 L->length - 1 then //結尾無空格 { 輸出空格 } }
2.1.3本題PTA提交列表說明
算法
本題要求實現順序表的操做集。
(1) List MakeEmpty():建立並返回一個空的線性表;數組
List MakeEmpty() { 聲明結構體指針q,用malloc分配內存; 給q->Last 賦值爲 -1表示爲空 返回 q; }
(2) Position Find( List L, ElementType X ):返回線性表中X的位置。若找不到則返回ERROR;
for循環遍歷順序表查找X的位置,找不到返回ERROR函數
Position Find(List L, ElementType X) { for (從0開始循環到順序表最後L->Last) { if (若是L->Data[i] 等於 X) { 返回位置i; } } 若是找不到返回 ERROR; }
(3)bool Insert( List L, ElementType X, Position P ):將X插入在位置P並返回true。若空間已滿,則打印「FULL」並返回false;若是參數P指向非法位置,則打印「ILLEGAL POSITION」並返回false;
先判斷是否合法,而後for循環查找插入位置,而後把插入位置以後的元素後移,把元素插入學習
bool Insert(List L, ElementType X, Position P) { if (若是最後元素位置L->Last 等於最大位置MAXSIZE-1) { 輸出( "FULL") 返回 false } if (若是P小於0或者大於最後元素位置) { 輸出( "ILLEGAL POSITION"); 返回 false; } if (若是P 小於等於 元素最後位置L->Last)須要移動元素 { for (i從最後位置L->next+1的位置循環到p) { L->Data中的i-1位置的元素移到i位置 } 經過循環後移結束後把L->Data[P]賦值爲X L->Last最後元素位置加一 } else 不須要移動 { 經過循環後移結束後把L->Data[P]賦值爲X L->Last最後元素位置加一 } 返回true }
(4) bool Delete( List L, Position P ):將位置P的元素刪除並返回true。若參數P指向非法位置,則打印「POSITION P EMPTY」(其中P是參數值)並返回false。設計
bool Delete(List L, Position P) { if (若是p不合法) { 輸出("POSITION %d EMPTY",P); 返回 false; } for (從頭遍歷一遍順序表) { if (若是目標P 不等於當前i) { 就把L->Data[j++]賦值爲L->Data[i]重構順序表 } } 最後順序表的最後元素位置L->Last減一 返回 true }
Q1:使用了new,可是題目是gcc編譯
Q2:在尾部刪除時沒有考慮到
Q3:輸出不對等小問題指針
設計函數分別求兩個一元多項式的乘積與和。code
結構體定義blog
typedef struct equation { 定義int類型係數 number; 定義int類型次方 power; 定義equation* 指針next; }EQU;//equation方程
(1) 建鏈表(比較簡單不詳細介紹)排序
void CreateList(EQU *&head,int &count) { 用new分配內存 用for循環不斷輸入 尾插法建鏈表 }
(2) 多項式加法
在循環中相同次方的係數相加或者不相等就把大的賦值到addresult中,直到兩個鏈表遍歷完畢索引
void EquationAdd(EQU* const &head1, EQU* const &head2,EQU* &addresult) { 用new分配內存,具體細節不表 聲明EQU指針q1來代替head1, q2來代替head2,temp爲臨時,p來代替addresult for (若是q1或q2不爲空) { 用new爲temp分配內存 if (若是q1和q2都不爲空) { if (若是q1->power 等於 q2->power)就合併 { 把temp->power 賦值爲q1->power 把temp->number 賦值爲 q1->number + q2->number q1和q2都等於下一個節點 } else把次方大的接到結果鏈表 { 而後該鏈表指針後移一個節點 } } else if(q1遍歷結束) { 就把q2的賦給temp } else q2遍歷結束 { 就把q1的賦給temp } 每次循環結束前把temp接到結果鏈表 } p->next = NULL }
(3) 多項式乘法
用兩個嵌套for把兩個鏈表相乘,結果保存在temp,而後調用插入函數
void EquationMultiply(EQU *const &head1, EQU *const &head2, EQU *&Multiplyresult) { 用new分配內存,具體細節不表 聲明EQU指針temp做爲臨時指針, p指針來代替Multiplyresult 聲明EQU指針q1來代替head1,q2來代替head2 if (q1或者q2爲空) { 結束函數 } for (若是q1遍歷還沒結束) { for (從q2頭循環到q2尾) { 把q1和q2相乘的結果保存到temp 調用插入函數InterList(Multiplyresult, temp) } } }
(4) 插入函數
結果鏈表是按次方從大到小排序,用for循環找到插入點插入,有次方等於的就合併
void InterList(EQU *&head,EQU *&temp) { 聲明EQU指針q和p來代替被插入鏈表,p指在q的前一個節點 for (經過q遍歷鏈表即q不爲空繼續循環) { 若是有次方相等就合併,沒有就插入 } }
(5)輸出函數
遍歷鏈表輸出,鏈表爲空等輸出相應提示(相對簡單,不詳述)
Q1:一開始沒有合併同類項
Q2:沒有去除零項
Q3:一開始沒有用插入函數,致使代碼複雜,小問題多,就寫了插入函數
給定一個鏈表,判斷鏈表中是否有環。
爲了表示給定鏈表中的環,咱們使用整數 pos 來表示鏈表尾鏈接到鏈表中的位置(索引從 0 開始)。 若是 pos 是 -1,則在該鏈表中沒有環。
經過使用具備 不一樣速度 的快、慢兩個指針遍歷鏈表,慢指針每次移動一步,而快指針每次移動兩步 ,若是列表中不存在環,最終快指針將會最早到達尾部,此時咱們能夠返回 false,若是有環快指針就必定會追上慢指針。
算法經典,時間複雜度o(n),空間複雜度o(1),我發現不少經典算法都是利用了兩個或多個指針對鏈表操做,取得了可觀的時間複雜度。