DS博客做業02--線性表

1.本週學習總結

1.1思惟導圖

1.2.談談你對線性表的認識及學習體會。

(1) 首先鏈表我上學期已有必定的基礎,因此學起來沒有太大的困難,可是解決問題時不夠老道,
沒有寫出的代碼時間複雜度不是太好,和老師舉例的算法有明顯差距,這方面還需多積累。
(2) 其次鏈表操做會涉及到指針,指針的用法又能夠至關巧妙,讓原本複雜的問題變簡單,
可是用很差可能會留下各類小bug,難以查找,甚至崩潰。因此要多多領悟總結。

2.PTA實驗做業

2.1.題目1:6-2 jmu-ds-有序表插入數據

實如今順序表中刪除某個區間數據。須要實現下述的三個函數完成該功能。
實現函數:
CreateSqList:建立有序表,連續輸入n個正數存入有序表中。L表示順序表指針,n表示輸入數據個數。
InsertSq(SqList *&L,int x):順序表L中插入數據x。
DispSqList:輸出順序表L中全部數據。數據間空格隔開,尾部不能有空格。

2.1.1設計思路

  • void CreateSqList(SqList &L, int n)建立有序表
用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
  • void InsertSq(SqList &L, int x)順序表L中插入數據x
    遍歷找到插入點而後後面元素後移
定義變量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
  • void DispSqList(SqList L)輸出順序表L中全部數據。數據間空格隔開,尾部不能有空格
for  (從i = 0 循環到 L->length)
    {
        輸出 L->data[i]
        if   i 小於 L->length - 1 then   //結尾無空格
        {
            輸出空格
        }
    }

2.1.2代碼截圖




2.1.3本題PTA提交列表說明
算法

  • Q1:代碼考慮不周全,插入結尾時會插入到前一個
  • A1;對插入結尾單獨判斷

2.2.題目2:6-4 順序表操做集

本題要求實現順序表的操做集。

2.1.1設計思路(僞代碼)

(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
}

2.1.2代碼截圖


2.1.3本題PTA提交列表說明


Q1:使用了new,可是題目是gcc編譯
Q2:在尾部刪除時沒有考慮到
Q3:輸出不對等小問題指針

2.3.題目3:7-2 一元多項式的乘法與加法運算

設計函數分別求兩個一元多項式的乘積與和。code

2.3.1設計思路(僞代碼)

結構體定義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)輸出函數
遍歷鏈表輸出,鏈表爲空等輸出相應提示(相對簡單,不詳述)

2.3.2代碼截圖






2.3.3本題PTA提交列表說明。


Q1:一開始沒有合併同類項
Q2:沒有去除零項
Q3:一開始沒有用插入函數,致使代碼複雜,小問題多,就寫了插入函數

三、閱讀代碼

3.1題目

給定一個鏈表,判斷鏈表中是否有環。
爲了表示給定鏈表中的環,咱們使用整數 pos 來表示鏈表尾鏈接到鏈表中的位置(索引從 0 開始)。 若是 pos 是 -1,則在該鏈表中沒有環。

3.2解題思路

經過使用具備 不一樣速度 的快、慢兩個指針遍歷鏈表,慢指針每次移動一步,而快指針每次移動兩步 ,若是列表中不存在環,最終快指針將會最早到達尾部,此時咱們能夠返回 false,若是有環快指針就必定會追上慢指針。

3.3代碼截圖

3.3學習體會

算法經典,時間複雜度o(n),空間複雜度o(1),我發現不少經典算法都是利用了兩個或多個指針對鏈表操做,取得了可觀的時間複雜度。
相關文章
相關標籤/搜索