數(shù)據(jù)結(jié)構(gòu)2019-11-29

? ?堆也被稱為優(yōu)先隊(duì)列,隊(duì)列是先進(jìn)先出,隊(duì)尾插入,隊(duì)頭刪除,而堆也是堆底插入,堆頂刪除。

? ? 棧先進(jìn)后出,棧頂插入和刪除。它是一種運(yùn)算受限的線性表。

隊(duì)列

? ??隊(duì)列是先進(jìn)先出,隊(duì)尾插入,隊(duì)頭刪除。動(dòng)態(tài)的創(chuàng)建,動(dòng)態(tài)是否,因而不存在溢出問題。

散列表

????又稱哈希表,是把關(guān)鍵碼根據(jù)映射函數(shù)映射到表中一個(gè)地址中,以加快查找速度。

? ? 散列地址沖突

? ? ? ? 是因?yàn)槎鄠€(gè)關(guān)鍵碼的映射地址相同。

? ? 解決方法? ? ? ? ? ??

? ? ? ? ?開放地址法:出現(xiàn)沖突,順序的尋找寫一個(gè)地址是否沖突,不沖突則放入,否則,繼續(xù)向下尋找。

? ? ? ? ? 鏈地址法:每個(gè)哈希地址單元為一個(gè)同義鏈表,來維護(hù)相同地址的關(guān)鍵碼。

二叉樹

? ? ? ? ? 第i層最大為2^(i-1),深度為k的二叉樹最多有2^k-1? 個(gè)結(jié)點(diǎn),n個(gè)結(jié)點(diǎn)高度至少log2(n+1)。任一棵二叉樹,n0=n2+1。

? ? ? ? ? 前序遍歷:

? ??????????//二叉樹前序遍歷遞歸

void?PreOrder(TreeNode*?root)

{

????if(root)

????{

????????cout?<<?root->val?<<?endl;

????????PreOrder(root->left);

????????PreOrder(root->right);

????}

}

//二叉樹前序遍歷非遞歸

void?PreOrder(TreeNode*?root)

{

????stack<TreeNode*>?s;

????while(root?!=?nullptr?||?!s.emtpy())

????{

????????if(root)

????????{

????????????s.push(root);

????????????cout?<<?root->val?<<?endl;

????????????root?=?root->left;

????????}

????????else

????????{

????????????root?=?s.top();

????????????s.pop();

????????????if(root)

????????????{

????????????????root?=?root->right;

????????????}

????????}

????}

}

? ? ? ? ? ? 中序遍歷:

//二叉樹中序遍歷遞歸

void?InOrder(TreeNode*?root)

{

????if(root)

????{

????????InOrder(root->left);

????????cout?<<?root->val?<<?endl;

????????InOrder(root->right);

????}

}

//二叉樹中序遍歷非遞歸

void?InOrder(TreeNode*?root)

{

????stack<TreeNode*>?s;


????????while(root)

????????{

????????????s.push(root);

????????????root?=?root->left;

????????}

????????if(!s.empty())

????????{

????????????root?=?s.top();

????????????cout?<<?root->val?<<?endl;

????????????s.pop();

????????????if(root)

????????????{

????????????????root?=?root->right;

????????????}

????????}

}

? ? 后序遍歷:

//二叉樹后序遍歷遞歸

void?PostOrder(TreeNode*?root)

{

????if(root)

????{

????????PostOrder(root->left);

????????PostOrder(root->right);

????????cout?<<?root->val?<<?endl;

????}

}

//二叉樹后序遍歷非遞歸

void?PostOrder(TreeNode*?root)

{

????TreeNode*?cur;

????TreeNode*?pre?=?nullptr;

????stack<TreeNode*>?s;


????????if(root)

????????{

????????????s.push(root);

????????}

????????while(!s.empty())

????????{

????????????cur?=?s.top();

????????????if(cur->left?==?nullptr?&&?cur->right?==?nullptr?||?pre?&&?(cur->left?==?pre?||?cur->right?==?pre))

????????????{

????????????????cout?<<?cur->val?<<?endl;

????????????????pre?=?cur;

????????????????s.pop();

????????????}

????????????else

????????????{

????????????????if(cur->right)

????????????????{

????????????????????s.push(cur->right);

????????????????}

????????????????if(cut->left)

????????????????????s.push(cur->left);

????????????}

????????}

}

? ? ? ? 層次遍歷:

//層次遍歷

void?LevelOrder(TreeNode*?root)

{

????if(root?==?nullptr)

????????return;

????queue<TreeNode*>?q;

????if(root)

????????q.push(root);

????while(!q.empty())

????{

????????TreeNode*?tmp?=?q->front();

????????cout?<<?tmp->val?<<?endl;

????????q.pop();

????????if(tmp->left)

????????{

????????????q.push(tmp->left);

????????}

????????if(tmp->right)

????????{

????????????q.push(tmp->right);

????????}

????}

}

二叉查找樹:

? ? ? ? 又稱二叉搜索樹,二叉排序樹。即中序遍歷有序,若左子樹不空,則左子樹的值都小于根結(jié)點(diǎn)的值,若右子樹不空,右子樹的值都大于根結(jié)點(diǎn),不存在值相同的結(jié)點(diǎn)。

完全二叉樹:

? ? ? ? 只有最小兩層的結(jié)點(diǎn)度小于2,且全都左連續(xù)。

平衡二叉樹:

? ? ? ? 每個(gè)結(jié)點(diǎn)的左子樹和右子樹高度差不超過1。

b 樹、b+ 樹

??????? 首先 b 樹屬于多叉樹又名平衡多路查找樹

其規(guī)則是

所有節(jié)點(diǎn)關(guān)鍵字是按遞增順序排列,并遵循左小右大規(guī)則

子節(jié)點(diǎn)數(shù),非葉子節(jié)點(diǎn)的子節(jié)點(diǎn)數(shù)大于 1 且小于 M,且 M > 2,空樹除外

關(guān)鍵字?jǐn)?shù),枝接點(diǎn)的關(guān)鍵字?jǐn)?shù)量大于等于 ceil(m/2)-1 個(gè)且小于等于 M-1 個(gè)(注:ceil() 是個(gè)朝正無窮方向取整的函數(shù),比如 ceil(1,1) = 2)

葉節(jié)點(diǎn)的指針為空且葉節(jié)點(diǎn)具有相同的深度

????????而對于 b+ 樹,是 b 樹的一個(gè)升級版,相對于 b 樹而言 b+ 樹更充分利用了節(jié)點(diǎn)的空間,讓查詢速度更加穩(wěn)定,其速度完全接近二分查找。

紅黑樹:

? ? ? ? 一種特殊的二叉查找樹。

? ? ? ?特性:

? ? ? ? ? ? 1、每個(gè)結(jié)點(diǎn)非紅即黑。

? ? ? ? ? ? 2、根結(jié)點(diǎn)黑色。

? ? ? ? ? ? 3、每個(gè)葉子結(jié)點(diǎn)黑色。

? ? ? ? ? ? 4、若結(jié)點(diǎn)為紅色,其子節(jié)點(diǎn)為黑色。

? ? ? ? ? ? 5、從一個(gè)結(jié)點(diǎn)到該子孫結(jié)點(diǎn)的所有路徑上包含相同數(shù)目的黑結(jié)點(diǎn)。

? ? ? ? ?紅黑樹的基本操作

紅黑樹的基本操作是添加、刪除,在對紅黑樹進(jìn)行添加刪除之后,都會(huì)用到旋轉(zhuǎn)方法(之所以要進(jìn)行旋轉(zhuǎn),是因?yàn)橐诓迦雱h除后還必須滿足紅黑樹的性質(zhì))

? ??????????左旋


? ? ? ? ? ? 右旋


紅黑樹如何進(jìn)行插入刪除?

插入

如果父節(jié)點(diǎn)為黑色,直接插入不處理

如果父節(jié)點(diǎn)為紅色,叔叔節(jié)點(diǎn)為紅色,則父節(jié)點(diǎn)和叔叔節(jié)點(diǎn)變?yōu)楹谏?,祖先?jié)點(diǎn)變?yōu)榧t色,將節(jié)點(diǎn)操作轉(zhuǎn)換為祖先節(jié)點(diǎn)

如果當(dāng)前節(jié)點(diǎn)為父親節(jié)點(diǎn)的右節(jié)點(diǎn),則以父親結(jié)點(diǎn)為中心左旋操作

如果當(dāng)前節(jié)點(diǎn)為父親節(jié)點(diǎn)的左節(jié)點(diǎn),則父親節(jié)點(diǎn)變?yōu)楹谏嫦裙?jié)點(diǎn)變?yōu)榧t色,以祖先節(jié)點(diǎn)為中心右旋操作

刪除

先按照排序二叉樹的方法,刪除當(dāng)前節(jié)點(diǎn),如果需要轉(zhuǎn)移即轉(zhuǎn)移到下一個(gè)節(jié)點(diǎn)

當(dāng)前節(jié)點(diǎn),必定為這樣的情況:沒有左子樹。

刪除為紅色節(jié)點(diǎn),不需要處理,直接按照刪除二叉樹節(jié)點(diǎn)一樣

如果兄弟節(jié)點(diǎn)為黑色,兄弟節(jié)點(diǎn)的兩個(gè)子節(jié)點(diǎn)為黑色,則將兄弟節(jié)點(diǎn)變?yōu)榧t色,將著色轉(zhuǎn)移到父親節(jié)點(diǎn)

如果兄弟節(jié)點(diǎn)為紅色,將兄弟節(jié)點(diǎn)設(shè)為黑色,父親結(jié)點(diǎn)設(shè)為紅色節(jié)點(diǎn),對父親結(jié)點(diǎn)進(jìn)行左旋操作

如果兄弟節(jié)點(diǎn)為黑色,左孩子為紅色,右孩子為黑色,對兄弟節(jié)點(diǎn)進(jìn)行右旋操作

如果兄弟節(jié)點(diǎn)為黑色,右孩子為紅色,則將父親節(jié)點(diǎn)的顏色賦值給兄弟節(jié)點(diǎn),將父親節(jié)點(diǎn)設(shè)置為黑色,將兄弟節(jié)點(diǎn)的右孩子設(shè)為黑色,對父親節(jié)點(diǎn)進(jìn)行左旋

紅黑樹、b 樹、b+ 樹區(qū)別

紅黑樹的深度比較大,而B+和B-的深度則相對要小一些,而B+較B-則將數(shù)據(jù)都保存在葉子節(jié)點(diǎn),同時(shí)通過鏈表的形式將他們連接在一起。

算法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容