我的coding練習(xí)

我的coding練習(xí)

二叉樹

L淋肾、D、R分別表示遍歷左子樹爸邢、訪問根結(jié)點(diǎn)和遍歷右子樹

  • 深度優(yōu)先遍歷:

    • 先(前)序遍歷:DLR : 只是為了遍歷
    • 中序遍歷:LDR : 順序輸出
    • 后序遍歷:LRD : 適合破壞性操作(delete等)
  • 廣度優(yōu)先遍歷:

    • 層序遍歷

僅有前序和后序遍歷樊卓,不能確定一個(gè)二叉樹,必須有中序遍歷的結(jié)果

遍歷

樹節(jié)點(diǎn)

struct BTN{
    int data_;
    BTN* left_;
    BTN* right_;
};

前序遍歷:DLR

  • 遞歸
void preOrderTraverse(BTN* p){
    if(p == nullptr){
        return;
    }
    print p->data_;
    preOrderTraverse(p->left_);
    preOrderTraverse(p->right_);
}
  • 非遞歸
void preOrderTraverse(BTN* p){
    if(p == nullptr){
        return;
    }
    std::stack<BTN*> stack;
    stack.push(p);
    while(!stack.empty()){
        p = stack.top();
        stack.pop();
        print(p->data_);
        if(p->right_){
            stack.push(p->right_);
        }
        if(p->left_){
            stack.push(p->left_);
        }
    }
}

中序遍歷:LDR

  • 遞歸
void preOrderTraverse(BTN* p){
    if(p == nullptr){
        return;
    }
    preOrderTraverse(p->left_);
    print p->data_;
    preOrderTraverse(p->right_);
}
  • 非遞歸
void inOrderTraverse(BTN* p){
    std::stack<BTN*> stack;
    while(p || !stack.empty()){
        if(p){
            stack.push(p);
            p = p->left_;
        }else{
            p = stack.top();
            stack.pop();
            print(p->data_);
            p = p->right_;
        }
    }
}

后序遍歷:DLR

  • 遞歸
void preOrderTraverse(BTN* p){
    if(p == nullptr){
        return;
    }
    preOrderTraverse(p->right_);
    preOrderTraverse(p->left_);
    print p->data_;
}
  • 非遞歸
struct TmpBTN{
    BTN* p_;
    bool visited_;
    TmpBTN(BTN* p):p_(p),visited_(false){}
};

void postorderTraversalNew(BTN *p)
{
    std::stack< TmpBTN > s;
    TmpBTN tmpBTN(p);
    s.push(tmpBTN);
    while(!s.empty())
    {
        tmpBTN = s.top();
        s.pop();
        if(tmpBTN.p_ == NULL)
            continue;
        if(tmpBTN.visited_)
        {
            print(tmpBTN.p_->data_);
        }else{
            //可以變換順序?yàn)槠渌闅v
            tmpBTN.visited_=true;
            s.push(tmpBTN);
            s.push(TmpBTN(tmpBTN.p_->right_));
            s.push(TmpBTN(tmpBTN.p_->left_));
        }
    }
}

層序遍歷:

void LevelOrderTraversal(BTN *p){
    std::queue<BTN*> q;
    q.push(p);
    while(!q.empty()){
        p = q.front();
        q.pop();
        if(p){
            print(p->data_);
            q.push(p->left_);
            q.push(p->right_);
        }
    }
}

實(shí)現(xiàn)stack和queue:

簡(jiǎn)單版本: List實(shí)現(xiàn)
template<class T>
struct Node{
    T data_;
    Node* next_;
    Node():next_(nullptr){}
    Node(const T& data):data_(data),next_(nullptr){}
};
template<T>
class Stack{
public:
    Stack():head_(nullptr){}
    ~Stack(){
        while(head_){
            Node<T>* toFreeNode = head_;
            head_ = head_->next_;
            delete toFreeNode;
        }
    }
    bool empty(){
        return head_ == nullptr;
    }
    void push(const T& data){
        try{
            Node<T>* newHead = new Node<T>(data);
            newHead->next_=head_;
            head_=newHead;
        }catch(std::bad_alloc& exception){
            throw exception;
        }
    }
    void pop(){
        if(empty()){
            //TODO execption 
        }else{
            Node<T>* toFreeNode = head_;
            head_ = head_->next_;
            delete toFreeNode;
        }
    }
    T top(){
        if(!empty()){
            return head_->data_;
        }else{
            //TODO execption 
        }
    }
private:
    Node<T>* head_;
};
//如果是queue就增加一個(gè)Node<T>* tail_;
優(yōu)化版本: vector實(shí)現(xiàn)
  • 注意擴(kuò)容與copy
template<class T>
class Queue{
public:
    Queue(uint32_t max_size):
        datas_(0),
        max_size_(max_size),
        size_(0),
        head_(0),
        tail_(0){
            datas_ = new T[max_size_];
        }
    ~Queue(){
        delete[] datas_;
    }
    bool empty(){
        return size_ == 0;
    }
    //TODO!
    void push(const T& data){
        if(size_ == max_size_){
            std::cout << "push:" << data << " failed !" << std::endl;
            return;
        }
        datas_[tail_] = data;
        Move(tail_);
        ++size_;
    }
    void pop(){
        if(empty()){
            std::cout << "pop: failed !" << std::endl;
        }else{
            Move(head_);
            --size_;
        }
    }
    T top(){
        if(!empty()){
            return datas_[head_];
        }else{
            std::cout << "top: failed !" << std::endl;
            return T();
        }
    }
private:
    T* datas_;
    uint32_t  max_size_;
    uint32_t  size_;
    int32_t head_;
    int32_t tail_;
    void Move(int32_t& cur){
        if(cur+1 < max_size_){
            ++cur;
        }else{
            cur = 0;
        }
    }
};

對(duì)于stackqueue的實(shí)現(xiàn)在STL中都是使用deque完成的甲棍,內(nèi)存分段分配結(jié)構(gòu)有點(diǎn)復(fù)雜简识,后續(xù)再分析。

queue是一種“先進(jìn)先出”的數(shù)據(jù)結(jié)構(gòu)感猛,可以對(duì)兩端進(jìn)行操作七扰,但是只能在隊(duì)列頭部進(jìn)行移除元素,只能在隊(duì)列尾部新增元素陪白,可以訪問隊(duì)列尾部和頭部的元素颈走,但是不能遍歷容器,所以queue不需要設(shè)計(jì)自己的容器咱士。在SGI STL的源碼<stl_queue.h>的class queue設(shè)計(jì)中立由,它是基于某種容器作為底部結(jié)構(gòu)的,默認(rèn)容器是deque容器序厉,用戶也可以自己指定容器的類型锐膜。
queue可以以deque和list作為底層的容器

單元測(cè)試:

struct BTN{
    int data_;
    BTN* left_;
    BTN* right_;
    BTN(int data):
        data_(data),
        left_(nullptr),
        right_(nullptr){}
};
//         4  
//    2       6
//  1   3       7

BTN* createBTN(){
    BTN* root = new BTN(4);
    root->left_ = new BTN(2);
    root->left_->left_ = new BTN(1);
    root->left_->right_= new BTN(3);
    root->right_ = new BTN(6);
    root->right_->right_ = new BTN(7);
    return root;
}

void print(int data){
    std::cout << data << std::endl;
}

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末弛房,一起剝皮案震驚了整個(gè)濱河市道盏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖荷逞,帶你破解...
    沈念sama閱讀 212,816評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件媒咳,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡种远,警方通過查閱死者的電腦和手機(jī)涩澡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)坠敷,“玉大人妙同,你說我怎么就攤上這事∠ビ” “怎么了渐溶?”我有些...
    開封第一講書人閱讀 158,300評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)弄抬。 經(jīng)常有香客問我,道長(zhǎng)宪郊,這世上最難降的妖魔是什么掂恕? 我笑而不...
    開封第一講書人閱讀 56,780評(píng)論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮弛槐,結(jié)果婚禮上懊亡,老公的妹妹穿的比我還像新娘。我一直安慰自己乎串,他們只是感情好店枣,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評(píng)論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著叹誉,像睡著了一般鸯两。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上长豁,一...
    開封第一講書人閱讀 50,084評(píng)論 1 291
  • 那天钧唐,我揣著相機(jī)與錄音,去河邊找鬼匠襟。 笑死钝侠,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的酸舍。 我是一名探鬼主播帅韧,決...
    沈念sama閱讀 39,151評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼啃勉!你這毒婦竟也來(lái)了忽舟?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,912評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎萧诫,沒想到半個(gè)月后斥难,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,355評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡帘饶,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評(píng)論 2 327
  • 正文 我和宋清朗相戀三年哑诊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片及刻。...
    茶點(diǎn)故事閱讀 38,809評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡镀裤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出缴饭,到底是詐尸還是另有隱情暑劝,我是刑警寧澤,帶...
    沈念sama閱讀 34,504評(píng)論 4 334
  • 正文 年R本政府宣布颗搂,位于F島的核電站担猛,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏丢氢。R本人自食惡果不足惜傅联,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望疚察。 院中可真熱鬧蒸走,春花似錦、人聲如沸貌嫡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)岛抄。三九已至别惦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間弦撩,已是汗流浹背步咪。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留益楼,地道東北人猾漫。 一個(gè)月前我還...
    沈念sama閱讀 46,628評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像感凤,于是被迫代替她去往敵國(guó)和親悯周。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評(píng)論 2 351