登录社区云,与社区用户共同成长
邀请您加入社区
为了检验红黑树的正确性,这里的输入数组为 41 67 34 0 69 24 78 58 62 64
最后的输出结果为:
62 黑
L[62] = 41 红
R[62] = 69 红
L[41] = 24 黑
R[41] = 58 黑
L[69] = 67 黑
R[69] = 79 黑
L[24] = 0 红
R[24] = 34 红
红黑树的节点
#pragma once #define RED 1 #define BLACK 2 class RBNode{ public: RBNode(); public: int key; RBNode* pParent; RBNode* pLeft; RBNode* pRight; int color; }; //左旋转 void LeftRotate(RBNode** proot, RBNode* x, RBNode* pguardNode); //右旋转 void RightRotate(RBNode** root, RBNode* x, RBNode* pguardNode); //插入 void RBInsert(RBNode** proot,RBNode* pnode, RBNode* pguardNode); //插入修正 void RBInsertFixup(RBNode** proot, RBNode* x, RBNode* pguardNode); //中序遍历 void InorderTreeWalk(RBNode* proot, RBNode* pguardNode); //采用中序遍历递归的方法在树中寻找一个元素 void FindNodeInBSTree(RBNode* proot, int key, RBNode** pnode,RBNode* pguardNode);
主要函数实现
// RBTRee.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "rbnode.h" #include<iostream> #include<stdlib.h> #include<time.h> #include<queue> using namespace std; #define random(x) (rand()%x) //一层一层遍历其中的元素 void LayerOrder(RBNode* proot,RBNode* pguardNode); // The Main Method int _tmain(int argc, _TCHAR* argv[]) { int num = 10; cout << "请输入需要排序数组的长度,数组将随机生成:" <<endl; cin >> num; int* ary = new int[num]; //srand( (int)time( 0 ) ); for ( int x=0; x<num; x++ ) { ary[x] = random(100); cout << ary[x] << endl; } //先生成一个不一定符合规则的红黑树,试试与二叉查找树相比修改后的插入方法是否正确 RBNode* proot = NULL; RBNode* pguardNode = new RBNode(); pguardNode->key = 111; pguardNode->color = BLACK; for ( int x=0; x<num; x++) { RBNode* pnode = new RBNode(); pnode->key = ary[x]; RBInsert( &proot, pnode, pguardNode ); } //逐层输出 cout << "逐层输出" << endl; LayerOrder( proot, pguardNode ); //中序遍历输出 /*cout << "中序遍历" << endl; InorderTreeWalk( proot, pguardNode );*/ //int nkey; //cout << "选择一个数" << endl; //cin >> nkey; //RBNode* pfindNode = NULL; //FindNodeInBSTree( proot, nkey, &pfindNode,pguardNode); //int LorR; //cout << "左旋转输入1,右旋转输入2" << endl; //cin >> LorR; //if ( LorR == 1 ) //{ // LeftRotate( &proot, pfindNode, pguardNode ); //} //else //{ // RightRotate( &proot, pfindNode, pguardNode ); //} //cout << "旋转完成" << endl; ////InorderTreeWalk( proot, pguardNode ); //LayerOrder( proot, pguardNode ); system("pause"); delete[] ary; return 0; } // void LayerOrder(RBNode* proot,RBNode* pguardNode) { //借用队列进行输出 std::queue<RBNode*> rbQueue; rbQueue.push( proot ); while ( !rbQueue.empty() ) { RBNode* p = rbQueue.front(); rbQueue.pop(); if ( p->pLeft != pguardNode ) { rbQueue.push( p->pLeft ); } if ( p->pRight != pguardNode ) { rbQueue.push( p->pRight ); } cout << "key=" << p->key << "color=" << p->color << endl; } } //左旋转 void LeftRotate(RBNode** proot, RBNode* px, RBNode* pguardNode) { //叶子节点不存在左旋还是右旋 if ( px->pLeft == pguardNode && px->pRight == pguardNode ) { return; } RBNode* y = px->pRight; //向左旋转,需要找到px的右子树 //将原先px的右子树修改指向y的左子树 px->pRight = y->pLeft; if ( y->pLeft != pguardNode ) { y->pLeft->pParent = px; //将y的左子树的父指针指向px } //修改px的父节点与px的联系,将y的父节点指向px,然后将px的父节点的子树指针指向y y->pParent = px->pParent; if ( px->pParent == pguardNode ) { *proot = y; } else { if ( px == px->pParent->pLeft ) { px->pParent->pLeft = y; } else { px->pParent->pRight = y; } } //重新建立px 与 y的子父关系 y->pLeft = px; px->pParent = y; } //右旋转 void RightRotate(RBNode** proot, RBNode* px, RBNode* pguardNode) { RBNode* y = px->pLeft; //修改y的右子树 px->pLeft = y->pRight; if ( y->pRight != pguardNode ) { y->pRight->pParent = px; } //修改px的父指针 y->pParent = px->pParent; if ( px->pParent == pguardNode ) { *proot = y; } else { if ( px == px->pParent->pLeft ) { px->pParent->pLeft = y; } else { px->pParent->pRight = y; } } //重新建立px与y的子父关系 y->pRight = px; px->pParent = y; } //中序遍历 void InorderTreeWalk(RBNode* proot, RBNode* pguardNode) { if ( proot != pguardNode && proot != NULL) { InorderTreeWalk( proot->pLeft, pguardNode ); cout << "key=" << proot->key << "/t" << "color="; proot->color == RED ? cout << "red" : cout << "black"; cout << endl; InorderTreeWalk( proot->pRight, pguardNode ); } } //采用中序遍历递归的方法在树中寻找一个元素 void FindNodeInBSTree(RBNode* x, int key, RBNode** pnode,RBNode* pguardNode) { if ( x != NULL && *pnode == NULL && x != pguardNode ) { //cout << "In Left"<< endl; FindNodeInBSTree( x->pLeft, key, pnode,pguardNode); //cout << "Out Left"<< endl; //cout << x->key << endl; if ( x->key == key ) { *pnode = x; //cout << "===========" << x->key << "============" << endl; return; } //cout << "In Right"<< endl; FindNodeInBSTree( x->pRight, key, pnode, pguardNode); //cout << "Out Right"<< endl; } } //插入 void RBInsert(RBNode** proot,RBNode* pnode, RBNode* pguardNode) { RBNode* y = pguardNode; RBNode* x = *proot; while ( x != pguardNode && x!= NULL ) { y = x; if ( pnode->key < x->key) { x = x->pLeft; } else { x = x->pRight; } } pnode->pParent = y; if ( y == pguardNode ) { *proot = pnode; } else { if ( pnode->key < y->key ) { y->pLeft = pnode; } else { y->pRight = pnode; } } pnode->pLeft = pguardNode; pnode->pRight = pguardNode; pnode->color = RED; RBInsertFixup( proot, pnode, pguardNode ); } //插入修正 void RBInsertFixup(RBNode** proot, RBNode* x, RBNode* pguardNode) { while ( x->pParent->color == RED ) { //x的父节点 == x的祖父节点的左子树 if ( x->pParent == x->pParent->pParent->pLeft ) { RBNode* y = x->pParent->pParent->pRight; if ( y->color == RED ) { x->pParent->color = BLACK; y->color = BLACK; x->pParent->pParent->color = RED; x = x->pParent->pParent; } else { if ( x == x->pParent->pRight ) { x = x->pParent; LeftRotate(proot,x,pguardNode); } x->pParent->color = BLACK; x->pParent->pParent->color = RED; RightRotate(proot,x->pParent->pParent, pguardNode); } }//end if x的父节点 == x的祖父节点的左子树 else// else x的父节点 == x的祖父节点的右子树 { RBNode* y = x->pParent->pParent->pLeft; if ( y->color == RED ) { x->pParent->color = BLACK; y->color = BLACK; x->pParent->pParent->color = RED; x = x->pParent->pParent; } else { if ( x == x->pParent->pLeft ) { x = x->pParent; RightRotate(proot,x,pguardNode); } x->pParent->color = BLACK; x->pParent->pParent->color = RED; LeftRotate(proot,x->pParent->pParent, pguardNode); } } }//end while loop (*proot)->color = BLACK; }
北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台
更多推荐
deck.gl TripsLayer 出租车轨迹动画示例实战:从示例运行到着色器原理
TripsLayer 是 deck.gl 中用于渲染**随时间流动的轨迹动画**(如出租车行程、物流路径、迁徙路线)的核心图层。本文以仓库中的最小独立示例 [examples/website/trips](https://link.gitcode.com/i/1442af8f442f4cff39ff546e050fceb5) 为骨架,带你完成从安装依赖、启动应用、理解曼哈顿出租车数据格式,到深入
Foundry Anvil 中 eth_simulateV1 的 Blob 交易与 Blob Gas 字段规范化:原理、实现与测试验证
本篇技术指南以 [anvil-simulate-blob-transactions.md](https://link.gitcode.com/i/3d2ebe227262de169335eb290af80da8) 这条 changelog 条目为起点,深入剖析 Foundry Anvil 对 `eth_simulateV1` RPC 返回结果中 blob(EIP-4844)交易与 blob gas
LMCache CLI 实战:用 `lmcache kvcache clear` 管理运行中服务的 KV Cache 状态
本文是一份针对 LMCache 官方 CLI 命令 `lmcache kvcache` 的完整技术指南。该命令用于在**运行中的 LMCache 服务(MP HTTP server)**上管理 KV cache 状态,当前提供 `clear` 子命令,用于清空 L1(CPU 内存)层中缓存的全部 KV 数据。读完本文,你将掌握该命令的完整参数体系、退出码语义、终端/JSON/静默三种输出模式,并能
扫一扫分享内容
为遵守国家网络实名制规定,未绑定将限制内容发布与互动
所有评论(0)