二叉樹的遍歷是按照一定的規則把二叉樹中的節點按照一定的次序排列成線性序列進行訪問的,實質上就是對乙個非線性結構進行線索化操作,使得每個節點(除第乙個和最後乙個外)都有前驅
和後繼節點,有時為了運算方便需要記錄這些前驅和後繼節點,稱為二叉樹線索化,而對於不同的遍歷規則,又分為先序線索二叉樹,中序線索二叉樹,後序線索二叉樹。
一顆具有n個節點的二叉樹,有n-1
條指向左孩子或右孩子的分支,對於二叉鍊錶來說,2n個指標只用了n-1個,所以可以利用另外n+1個指標作為指向前驅節點和後繼節點的指標。
有些書籍對這兩個概念並沒有簡單明瞭的解釋~,其實就是對於特定遍歷方式來說,乙個節點的前後節點
①前驅節點:
指定遍歷方式得出的節點訪問順序中,某一節點的前乙個節點。
②後繼節點
指定遍歷方式得出的節點訪問順序中,某一節點的後乙個節點。
#define link 0 //表示該節點有非空孩子節點
#define thread 1 //表示該節點有後續節點(對於右子樹來說)
templatestruct bt_thread_node
;
ltag=0(link)-表示left_child的指標指向左孩子節點;ltag=1(thread)-表示left_child的指標指向前驅節點rtag=0(link)-表示right_child的指標指向右孩子節點;rtag=1(thread)-表示right_child的指標指向後繼節點書上也是奇奇怪怪的,其實很簡單,就按照某一遍歷規則,記錄當前節點(cur),上一次訪問的節點(pre)
①如果當前節點cur->left_child=null(左孩子節點空),則cur->left_child=pre;cur->ltag=1(左指標域指向前驅節點(前乙個節點pre),修改ltag為線索模式)
②如果前一節點pre->right_child=null(前節點的右孩子節點空),則pre->right_child=cur;pre->rtag=1(前節點的右指標域指向後繼節點(也就是當前節點),修改rtag為線索模式)
inorder_thread_op(tree->right_child); //右
}注:pre_node是類內資料成員,初始化為null
①思路:
對於中序遍歷來說,先查詢線索鍊錶的第乙個節點,也就是最左方向上的最後乙個節點,然後如果有右線索先尋找後繼節點,查詢到斷線索(有右節點啦)就往下找乙個右節點,繼續這樣摸下去,其實說到底就是有線索先按線索找(注意線索上的節點是需要訪問的),等到線索斷了就往下找右孩子節點。
②實現**
templatevoid thread_binary_tree::_inorder_op(bt_thread_node* &tree)
cout << cur_node->data << " ";
while (cur_node&&cur_node->rtag == thread) //節點非空並且右樹是線索樹時查詢最前的乙個線索樹節點
cur_node = cur_node->right_child; //右樹不是線索樹,查詢該節點的右孩子節點
} cout << endl;
}
①思路:
當把樹線索化了,其實就是鍊錶,而刪除呢,我覺得按煉表刪就ok,但是後來發現腦子不好用,就想著按遍歷的順序,棧存節點,然後把棧清了就ok,所以再寫了乙個程式,寫了才發現其實!可以直接在遍歷的時候順便入棧了節點,好吧這次先這樣,等後面出先序和後序我再改吧~
②**
bt_thread_node* bt_node_stack[maxsize];//類私有,maxisize=100
templateint thread_binary_tree::distory_thread_btree(bt_thread_node* &tree)
bt_node_stack[++top] = cur_node;
while (cur_node&&cur_node->rtag == thread)
cur_node = cur_node->right_child;
} for (top; top != -1; top--)
return 1;
}
#includeusing namespace std;
#define link 0 //表示該節點有非空孩子節點
#define thread 1 //表示該節點有後續節點(對於右子樹來說)
#define maxsize 100
templatestruct bt_thread_node
;templateclass thread_binary_tree
;templateint thread_binary_tree::create_thread_btree(bt_thread_node* &tree)
return 1;
}templateint thread_binary_tree::distory_thread_btree(bt_thread_node* &tree)
bt_node_stack[++top] = cur_node;
while (cur_node&&cur_node->rtag == thread)
cur_node = cur_node->right_child;
} for (top; top != -1; top--)
return 1;
}templatevoid thread_binary_tree::inorder_thread_op(bt_thread_node* &tree)
if (pre_node != null && pre_node->right_child == null)
pre_node = tree;
inorder_thread_op(tree->right_child); //右
}templatevoid thread_binary_tree::_inorder_op(bt_thread_node* &tree)
cout << cur_node->data << " ";
while (cur_node&&cur_node->rtag == thread) //節點非空並且右樹是線索樹時查詢最前的乙個線索樹節點
cur_node = cur_node->right_child; //右樹不是線索樹,查詢該節點的右孩子節點
} cout << endl;
}templatethread_binary_tree::thread_binary_tree():pre_node(null)
templatethread_binary_tree::~thread_binary_tree()
templatevoid thread_binary_tree::inorder_thread()
templatevoid thread_binary_tree::_inorder()
二叉樹的中序線索樹 資料結構 線索二叉樹
1.引入線索二叉樹 二叉樹的遍歷實質上是對乙個非線性結構實現線性化的過程,使每乙個節點 除第乙個和最後乙個外 在這些線性序列中有且僅有乙個直接前驅和直接後繼。但在二叉鍊錶儲存結構中,只能找到乙個節點的左 右孩子資訊,而不能直接得到節點在任一遍歷序列中的前驅和後繼資訊。這些資訊只有在遍歷的動態過程中才...
資料結構 中序線索二叉樹
所謂線索二叉樹無非是為了讓原本指向null的節點指向乙個詳細的 已經存在的節點,邏輯上實現指標的無空指向的實現。以下是我中 序線索二叉樹的實現。還是把先序線索二叉樹與後序線索分開來寫吧。include using namespace std template struct node template...
中序線索二叉樹
就是在中序遍歷的時候加上線索,為了區分線索和孩子,要多加兩個標誌變數ltag,rtag如果標誌為true就表明是線索,如果為false就表示孩子 一般規定是將做指標為空的指標域用來存放直接前驅 將有指標為空的指標域用來存放直接後繼 當然如果不為空的話就不會用來存放前後繼,而是孩子了 意思就是存放前繼...