二叉樹的建立及遍歷

2021-07-29 12:38:05 字數 4303 閱讀 2217

在資料處理的過程中,二叉樹的大小和形態不會發生劇烈變化的情況下,適合用陣列來表示二叉樹的抽象資料型別。

完全二叉樹一般由陣列儲存表示,而一般二叉樹則是用鍊錶儲存表示的。

本篇將採用二叉鏈的儲存方式對二叉樹進行儲存。

二叉樹的建立,使用遞迴前序構建二叉樹。先建立根節點,在對左子樹進行建立,左子樹建立完成後,又對右子樹進行建立。當遇到非法值時表示該子樹建立完成。

前序遍歷:根節點->左節點->右節點

遞迴:列印根節點的資料,列印右子樹的所有資料,列印左子樹的所有資料。

非遞迴:定義乙個棧,將根節點壓棧並訪問,依次將左子樹壓棧,左子樹同樣相當於一棵完整的樹,重複此過程。若左子樹訪問完成,則將最後乙個左子樹退棧,訪問上乙個節點的右子樹,依次類推,最終將會遍歷整個子樹。

中序遍歷及後序遍歷與前序遍歷類似,不同的是:

中序遍歷先訪問左子樹,再訪問根節點,最後訪問右子樹。非遞迴實現中序遍歷時,同樣將根節點壓棧,但是不進行訪問,在左子樹遍歷完成後進行訪問。

後序遍歷先訪問左子樹,再訪問右子樹,最後訪問根節點。非遞迴實現後序遍歷時,將根節點壓棧,訪問左子樹,完成後訪問右子樹,將右子樹訪問完成後再訪問其根節點。

層序遍歷使用佇列實現。

二叉樹的建立,遍歷及一些簡單操作的**如下:

templatestruct binarytreenode              //二叉樹的節點

};templateclass binarytree

binarytree(t* array, size_t n, const t&invalid = t()) //前序構建二叉樹

void prevorderr() //用遞迴的方法前序遍歷

void prevordernonr() //非遞迴前序遍歷

node* top = s.top();

s.pop();

cur = top->_right;

} cout << endl;

} void inorderr() //用遞迴的方法中序遍歷

void inordernonr() //非遞迴中序遍歷

node* top = s.top();

cout << top->_data << " ";

s.pop();

cur = top->_right;

} cout << endl;

} void postorderr() //用遞迴的方法後序遍歷

void postordernonr() //非遞迴前序遍歷

node* top = s.top();

if (top->_right == null || top->_right == prev)

else

}cout << endl;

} void levelorder() //層序遍歷

while (!q.empty())

if (front->_right)

}cout << endl;

} size_t depth()

//size_t sizer() //遞迴實現求節點個數

// size_t sizer() //遞迴實現求節點個數

size_t getleafsizer() //遞迴求葉節點個數

size_t getkleafsizer(size_t k) //遞迴求第k層節點個數

node* findr(const t& x) //遞迴查詢乙個數字的位置

binarytree(const binarytree& t) //拷貝構造

:_root(null)

binarytree& operator=(const binarytree&t) //賦值運算子過載 }

~binarytree() //析構函式

protected:

size_t _depth(node* root)

int left = _depth(root->_left);

int right = _depth(root->_right);

return left > right ? left : right;

} node* _copytreer(node* root)

return head;

} void _destroyr(node* root) }

node* _creattreer(t* array, size_t n, const t& invalid, size_t& index)

return root;

} void _prevorderr(node* root)

cout << root->_data << " ";

_prevorderr(root->_left);

_prevorderr(root->_right);

} void _inorderr(node* root)

_inorderr(root->_left);

cout << root->_data << " ";

_inorderr(root->_right);

} void _postorderr(node* root)

_postorderr(root->_left);

_postorderr(root->_right);

cout << root->_data << " ";

} //size_t _sizer(node* root)

// // return _sizer(root->_left) + _sizer(root->_right) + 1;

//}size_t _sizer(node* root, size_t& count)

++count;

_sizer(root->_left, count);

_sizer(root->_right, count);

return count;

} size_t _getleafsizer(node* root)

if (root->_left == null && root->_right == null)

else

}size_t _getkleafsizer(node* cur, size_t k)

if (k == 1)

else

}node* _findr(node* root, const t& x)

if (root->_data == x)

node* cur = _findr(root->_left, x);

if (cur)

else

}protected:

node* _root;

};

測試用例為:

void testbinarytree()

; binarytreet1(array1, sizeof(array1) / sizeof(array1[0]), '#');

cout << "t1.prevorderr: ";

t1.prevorderr();

cout << "t1.prevordernonr: ";

t1.prevordernonr();

cout << "t1.inorderr: ";

t1.inorderr();

cout << "t1.inordernonr: ";

t1.inordernonr();

cout << "t1.postorderr: ";

t1.postorderr();

cout << "t1.postordernonr: ";

t1.postordernonr();

cout << "t1.levelorder: ";

t1.levelorder();

cout << "t1.size: " << t1.sizer() << endl;

cout << "t1.depth: " << t1.depth() << endl;

cout << "t1.k層節點個數: " << t1.getkleafsizer(3) << endl;

cout << "t1.葉節點個數: " << t1.getleafsizer() << endl;

binarytreet2(t1);

cout << "t2.prevorderr: ";

t2.prevorderr();

二叉樹的建立及遍歷

對任意的二叉樹的結點結構都可以設定為如下結構,leftchild指向該結點的左孩子,rightchild指向右孩子,data域記錄結點資訊,以此結點結構形成的二叉樹稱為二叉鍊錶。儲存結構型別為 typedef char elemtype typedef struct nodebitnode,bitr...

二叉樹及二叉樹的遍歷

二叉樹的定義 樹的度為2的樹。二叉樹的遞迴定義 二叉樹或者是一棵空樹,或者是一棵由乙個根結點和兩棵互不相交的左子樹和右子樹所組成的非空樹,而左右子樹又都是一棵二叉樹。1.第i層上至多有2的i 1次方個結點。2.深度為h的二叉樹至多有2的h次方減1個結點。3.每一層都滿的二叉樹稱為滿二叉樹,只在最後一...

線索二叉樹建立及遍歷

層序輸入 中序遍歷建立線索二叉樹 利用頭節點遍歷線索二叉樹 include using namespace std typedef char elemtype define maxsize 100 enum tag 二叉鍊錶的結構建立 typedef struct bitnodebitnode,bi...