DS博客做業07--查找

1.本週學習總結

思惟導圖

談談你對查找運算的認識及學習體會

在學習本章的知識前,咱們得先掌握以前的二叉樹的內容,這樣才能順利的掌握課本知識。在編程前要先想清楚思路再開始寫代碼,靈活地利用書上的知識。對於書上的算法代碼,咱們必定要仔細鑽研每一步的具體含義和目的,在此基礎上深刻的瞭解算法的實現過程,在查找時利用書中給出的各類方法能夠極大地減小時間複雜度,從而提升查找速度,使算法更加簡單。不少時候單看書上的內容會以爲很簡單,可是真正作起來又很容易忘東忘西,因此增長實際應用經驗很重要。算法

2.PTA實驗做業

2.1.題目1:QQ賬戶的申請與登錄

實現QQ新賬戶申請和老賬戶登錄的簡化版功能。最大挑戰是:聽說如今的QQ號碼已經有10位數了。編程

2.1.1設計思路

main函數{
定義整型數N;
定義字符 c;
輸入N;
定義結構體數組a[N];
定義map QQ;
for i=0 to N
    輸入c,a[i].qq,a[i].code;
    if 輸入‘N’  //註冊帳號
        if QQ.find(a[i].qq)等於QQ.end() //map查找qq帳號,若是帳號不存在
            QQ[a[i].qq]=a[i].code;
            輸出"New: OK"; //帳號建立成功
        else 輸出「ERROR: Exist」; //qq帳號已存在,建立失敗
    else if 輸入‘L’ //登陸帳號
    if QQ.find(a[i].qq)等於QQ.end()  //map查找qq帳號,若是帳號不存在 
        輸出"ERROR: Not Exist";
    else
        if QQ[a[i].qq]等於a[i].code  //若是帳號和密碼匹配成功 
            輸出「Login: OK」;
        else
            輸出「ERROR: Wrong PW」;

return 0;
        
}

2.1.2代碼截圖


2.1.3本題PTA提交列表說明

  • 原本想的思路比較複雜,但後來發現用map會很簡單。
  • 在登陸的那幾行代碼中由於if else語句疊了三層因此有些邏輯混亂,致使總是找不出錯誤緣由。數組

    2.2.題目2:二叉搜索樹中的最近公共祖先

    在一棵樹T中兩個結點u和v的最近公共祖先(LCA),是樹中以u和v爲其後代的深度最大的那個結點。現給定某二叉搜索樹(BST)中任意兩個結點,要求你找出它們的最近公共祖先。函數

    2.2.1設計思路

LCA函數{
定義兩個樹節點指針t,s;
定義一個flag;
if 樹爲空 返回 ERROR
while t不爲空
    if 當前節點等於u
        flag++;
        break;
    else if 當前節點大於u 
        t等於它的左孩子
    else t等於它的右孩子
while s不爲空
    if 當前節點等於v
        flag++;
        break;
    else if 當前節點大於v 
        t等於它的左孩子
    else t等於它的右孩子

if flag不等於2說明u,v有一個不在二叉樹內,返回ERROR

while T的左右孩子有一個不爲空
    if T.Key等於u或者等於v 
        return T->Key;
    if T->Key大於u且T->Key小於v或T->Key小於u且T->Key大於v
        return T->Key;
    if T->Key 大於 u和v
        T等於它的左孩子;
    if T->Key 小於 u和v
        T等於它的右孩子;
}

2.2.2代碼截圖


2.2.3本題PTA提交列表說明

  • Q1:剛開始提交只對了三個測試點,發現是檢查u和v是否在二叉樹的代碼有誤。
  • A1:將兩個循環中的else if語句中的條件修改了。
  • Q2:當LCA是自己時的測試點過不去。
  • A2:添加了補充條件後仍過不了,發現是總的循環條件寫錯了,致使只能遍歷到左右孩子都有的節點,最後把&&改爲||就對了。

2.3.題目3:二叉搜索樹的操做集

本題要求實現給定二叉搜索樹的5種經常使用操做。學習

2.3.1設計思路

Insert函數{
    if BST爲空
        BST->Data等於X;
        BST的左右孩子都置爲空;
    else if X不等於BST->Data
        if X小於BST->Data
            BST->Left等於Insert(BST->left,X);
        else
            BST->Left等於Insert(BST->left,X);
return BST;
}

Delete函數{
定義樹節點 q;
if BST爲空 輸出"Not Found\n";
else{
    if(X小於BST->Data)
        BST左孩子等於Delete(BST->Left,X);
    else if(X大於BST->Data)
    {
        BST右孩子等於Delete(BST->Right,X);
    }
    else  //考慮若是找到這個位置,而且有左節點或者右節點或者沒有節點三種狀況
        {
            if BST的左右孩子都在 {
                q=FindMin(BST->Right);  
                BST->Data=q->Data;
                BST->Right=Delete(BST->Right,BST->Data);
            }
            else
            {                                
                q=BST;
                if(左孩子爲空) BST = BST->Right;       
                else if(右孩子爲空) BST = BST->Left;
                釋放q;                         
            }
       }
    }
    return BST;
}

Find函數{
    if(BST爲空) return NULL;
    if(BST->Data等於X) return BST;
    else if(X小於BST->Data) {
        return Find(BST->Left,X);
    }
    else if(X大於BST->Data)
    {
        return Find(BST->Right,X);
    }
    return BST;
}

FindMin函數{
    if(BST不爲空)
    {
        while(BST的左孩子不爲空)
            BST=BST->Left;
    }
    return BST;
}

FindMax函數{
    if(BST不爲空)
    {
        while(BST的右孩子不爲空)
             BST=BST->Right;
    }
    return BST;
}

2.3.2代碼截圖




2.3.3本題PTA提交列表說明

  • 在寫刪除函數代碼時,參考書上的思路會時本身的思路比較清晰

3.閱讀代碼

3.1 題目:是否徹底二叉搜索樹

3.2 解題思路

徹底二叉樹的定義是:若設二叉樹的深度爲h,除第 h 層外,其它各層 (1~h-1) 的結點數都達到最大個數,第 h 層全部的結點都連續集中在最左邊。
由於右子樹的結點編號是父節點的兩倍,而左子樹的結點編號是父節點的兩倍加一,因此能夠用數組模擬建樹的過程。最後題目要求層序輸出,直接按編號大小輸出。而最後一行的結點編號和n相等。測試

3.3 代碼截圖


3.4 學習體會

本題定義了一個數組a來模擬建樹的過程使代碼變得更加簡單,這要求要掌握徹底二叉樹的概念和性質,瞭解左子樹的結點編號和它父結點的結點編號的關係。在判斷是否爲徹底二叉樹時,他巧妙地利用結點數和i來判斷。當置數組a的初值時他用到了memset函數,但咱們本身在使用memset時要千萬當心,要知道在給char之外的數組賦值時,只能初始化爲0或者-1。設計

相關文章
相關標籤/搜索