C++day15 學習筆記

來源:互聯網
上載者:User

1、在標頭檔中

  #ifndef _ACCOUNT_   //先行編譯選項,表示如果沒有定義這個宏  #define _ACCOUNT_   //建立以_ACCOUNT_命名的宏                        並聲明類  #endif 

2、鏈表
   (1)解決數組必須連續儲存的問題
        鏈表是可以不連續的,通過每個節點的指標串連
   (2)節點中一部分空間用於存放資料,另一部分是一個指向下一個節點的指標       
   (3)每個節點都是一個結構

       struct node{             int data;    //儲存資料             node* next;  //指向下一個節點的指標,是自己這個結構的類型        }

   (4)尾節點 --- 鏈表中的最後一個節點 --- 指標指向NULL
        前端節點 --- 要訪問鏈表中的元素,必須要知道前端節點的位置
                   把地址放在一個指標中 --- 頭指標指向前端節點,只是一個指標 --- 是必須存在的元素
   (5)對鏈表的常見操作 --- 增刪改查
   (6)鏈表與數組的區別
        數組:空間必須連續,數組是定長的,插入和刪除需要遍曆整個數組,效率不高。
              取元素可直接使用下標,訪問方便
        鏈表:空間在記憶體中不必連續,通過指標串連
              鏈表是不定長的,可以隨時添加新節點,通過指標關聯
              對鏈表的插入刪除,不需要移動節點位置,只對指標操作即可
              訪問元素,要從頭指標開始遍曆
             
        當資料需要頻繁的插入刪除的時候,需要使用鏈表
        當改動不大,查詢頻繁的時候,使用數組
        潛規則 : 能用數組就不用鏈表

View Code

        ======================================================================                                      link.h        ======================================================================        #ifndef _LINK_        #define _LINK_        using namespace std;        class Node{  //節點類         public :              int val;      //儲存資料               Node* next ;  //儲存下一個節點的地址               Node(){       //建構函式,把指標初始化為NULL                  next = NULL;                     }             };        class Link{        protected :             Node* head;   //頭指標         public :             Link();             ~Link();             void insertTail(int);             void insertHead(int);             void del(int);             int indexOf(int); //查詢一個元素的下標             void update(int , int);             void disp();                            };        #endif
View Code

        ======================================================================                                  link.cc        ======================================================================                                            #include "link.h"        #include <iostream>        using namespace std;        Link::Link(){           head = NULL;                     }        Link:: ~Link(){//釋放空間,從頭向尾釋放             if(head != NULL){                Node *p = head;                head = head->next; //把前端節點向後移動                 delete p;          //拋棄原來的那個前端節點                cout << "delete one ... " << endl;             }        }        //尾插入         void  Link::insertTail(int v){              Node *p = new Node;              p->val = v;                 if(head == NULL){                   head = p;   //讓新節點的指標指向新節點,即把新節點的地址儲存在頭指標中                   return ;                      }               Node * temp = head ; //用一個臨時指標,從前端節點開始找到 尾              while(temp -> next != NULL){  //表示temp不是尾節點                    temp = temp -> next ; //用temp後面的一個指標為自己賦值,即指向下一個節點               }               temp -> next = p;  //尾插入,最後一個節點的指標儲存新節點的地址          }         //頭插入          void  Link::insertHead(int v){               Node *p = new Node;  //建立新節點                p->val = v ;         //儲存資料                p->next =  head;     //讓新節點的指標和頭指標一樣指向第一個節點                head = p;            //讓前端節點指向新節點          }         void  Link::del(int v){   //找到被刪除的節點 ,               if(head == NULL ){                     return ;                       }                   if(head -> val == v){                     Node *p = head;                     head = head->next;                     delete head;               }                             Node *p1 = head->next; //找值相同的一個                Node *p2 = head ;      //跟在p1後面               while(p1 != NULL){                   if(p1->val == v){                        p2->next = p1 -> next;                        delete p1;                        break;                    }                               p1 = p1->next;                    p2 = p2->next;                 }           }                    int  Link::indexOf(int v){ //查詢一個元素的下標                  Node * p = head ;                  int counter = 0 ;                  while( p != NULL ){                         if( p->val == v ){                                return counter ;                          }                          p=p->next ;                          counter++ ;                  }                  return -1 ;                }            void  Link::update(int v1 , int v2){                   Node * p = head ;                   while( p != NULL ){                            if( p->val == v1 ){                                  p->val = v2 ;                            }                            p = p->next ;                     }                        }          void  Link::disp(){                 Node *p = head;                 while(p != NULL){                       cout << p->val << " " ;                               p = p->next;                 }                       cout << endl;          }

3、二叉樹
   每個節點最多隻有兩個分支的樹,它有一個根指標,要指向這棵樹的根節點(最頂端的節點).
   左子樹上的值小於其父節點的值,右子樹上的值都大於其父節點上的值。    ---  排序二叉樹
   (1)周遊(遍曆) :先序  ---  中左右
                       中序  ---  左中右    
                       後序  ---  左右中
   (2)非常方便尋找

二叉尋找樹的常見操作:
1) 插入. 範例程式碼如下:

View Code

Node* Tree::_insert(int v, Node* r){  //真正實現插入操作,返回插入以後的根     if(r == NULL){         //是一棵空樹 (空子樹)         Node* p = new Node(v); //建立新節點         r = p;                 //讓新節點成為根或者子節點         return r;    }    if( v < r->val){  //插到左子樹上         r->left = _insert(v,r->left);        return r;    }else{            //插到右子樹上         r->right = _insert(v,r->right);              return r;    }}

2) 尋找. 範例程式碼如下:

View Code

    Node* & find( bnode* & root, const DATA& cd )    {        if( root==NULL )                    // 如果root節點是空,則為空白樹            return root;                    // 返回root指向的地址,即NULL        else if( root->data==cd )           // 如果root節點就是要尋找的數值            return root;                    // 返回root指向的地址,為了清晰,和上面的分開寫        else if( cd < root->data )          // 如果root節點指向的值大於要尋找的值            return find( root->left, cd );  // 返回尋找root的左子樹返回的地址        else            return find( root->right, cd ); // 否則返回尋找root的右子樹返回的地址    }

3) 刪除. 範例程式碼如下:
   被刪除的是樹根(1)則選擇右子樹的樹根做新樹根,左子樹可以整個掛在右子樹最左側的一個左節點上
                      右子樹中最左邊的一個節點,是最靠近左子樹的樹根的     
                 (2)讓左子樹中的最大節點做新樹根

View Code

Node* _del( int value , Node* r ){        if( r == NULL ){       //刪除空樹            return r ;        }        if( r->value == value ){        //刪除樹根             if(r->left==r->right){      //左右子樹都是NULL的情況下                   delete r ;            return NULL;        }else if( r->right == NULL ){  //只有右子樹,沒有左子樹的時候                    Node * p = r;                  r = r->left ;                  delete p ;                  return r ;            }else if( r->left == NULL ){   //只有右子樹,沒有左子樹                   Node *p = r ;                  r=r->right ;                  delete p ;                  return r ;            }else{                          //左右子樹都有                  Node * p1 = r -> right ;                  Node * p2 = r -> right ;                  while( p2->left != NULL ){                        p2 = p2->left ;                  }                      p2->left = r->left ;                      delete r ;                  return p1 ;            }        }        if( value <= r->value ){              r->left = _del( value , r->left);              return r ;        }else{              r->right =_del( value, r->right );              return r ;        }            return r ;}

作業:修改鏈表程式,能夠刪除全部相同元素;在指定位置後插入資料

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.