二查排序树的基本操作(插入,删除,找前驱与后继)
2016-09-27 12:28
288 查看
// Binary-Search-Tree.cpp : Defines the entry point for the console application. //最近要面试,想自己写写这类算法的代码,加深印象 #include "stdafx.h" //参考算法导论的伪代码编写 //有错误的地方,恳请大家批评指正,thx; typedef struct Node { int val; Node* left; Node* right; Node* parent; Node(int value) : val(value) , left(NULL), right(NULL),parent(NULL) { } }Node; //查找二叉搜索树中最小的元素 int FindMinValue(Node* head) { if(head == NULL) return -1; Node* p = head; while(p->left) p = p->left; return p->val; } //查找二叉搜索树的最大元素 int FindMaxValue(Node* head) { if(head == NULL) return -1; Node* p = head; while(p->right) p = p->right; return p->val; } //找当前节点的后继结点 /* 1、若当前节点有右子树,那么后继结点就是右子树最左的结点 2、若当前节点没有右子树, 那么后继结点:从当前节点往上延伸,找到某个结点p,p不是其父结点的右孩子。如果找不到结点p,则其没有后继结点 */ Node* FindSucceed(Node* curNode) { if(curNode->right) { Node* p = curNode->right; while(p->left) p = p->left; return p; } else { Node* cur = curNode; Node* parent = curNode->parent; while(parent && parent->right == cur) { cur = parent; parent = cur->parent; } /*if(parent == NULL) return NULL; else return parent;*/ return parent; } } //找当前节点的前驱结点 /* 1、如果当前节点有左子树,那么前驱结点就是其左子树最右的结点 2、如果当前节点没有左子树,则前驱结点:从当前节点往上延伸,找到结点p,p不是其父结点的左孩子。如果找不到结点p,则该节点没有前驱结点; */ Node* FindPioneer(Node* curNode) { if(curNode->left) { Node* p = curNode->left; while(p->right) p = p->right; return p; } else { Node* cur = curNode; Node* parent = cur->parent; while(parent && parent->left == cur) { cur = parent; parent = cur->parent; } return parent; } } //二叉树中插入结点 void InsertNode(Node* head, Node* node) { if(node == NULL) return; Node* parent = NULL; Node* curNode = head; while(curNode) { parent = curNode; if(curNode->val > node->val) curNode = curNode->left; else curNode = curNode->right; } node->parent = parent; if(parent == NULL) node = head; else if(parent->val < node->val) parent->right = node; else parent->left = node; } //二叉树中删除结点 /* 分三种情况讨论 1、如果删除结点没有左孩子也没有右孩子,则可以直接删除改结点,并让其父结点孩子指针为NULL; 2、如果删除结点只有一个孩子结点,则也可以直接删除该节点,并让其父结点的孩子指针指向删除结点的孩子; 3、如果删除结点有两个孩子结点,则先找到该节点的后继结点,后继结点的元素值取代删除结点的元素值,再删除后继结点,并让后继结点的父节点的孩子指针指向后继结点的孩子; */ void DeleteNode(Node* head, Node* node) { Node* y, *x; if(node->left==NULL || node->right==NULL) y = node; else y = FindSucceed(node); if(y->left) x = y->left; else x = y->right; if(x) { x->parent = y->parent; } if(y->parent == NULL) head = x; else if(y == y->parent->left) y->parent->left = x; else y->parent->right = x; if(y != node) { node->val = y->val; delete y; } } int _tmain(int argc, _TCHAR* argv[]) { return 0; }
相关文章推荐
- java语言编写链表的基本操作(链表的创建,插入,删除,打印,排序)
- 写给初学数据结构的同学之(循环双链表基本操作,创建,插入,删除,排序)
- 程序员面试宝典(第三版)——单链表的基本操作:建立,求长度,输出,排序,插入,删除,逆置
- 排序二叉树BST的基本操作(2)前驱,后继,删除
- 堆的基本操作:定义、创建、插入、删除、排序
- 单链表的基本操作:建立,求长度,输出,排序,插入,删除,逆置
- 程序员面试宝典(第三版)——单链表的基本操作:建立,求长度,输出,排序,插入,删除,逆置(转)
- 排序二叉树BST的基本操作(2)前驱,后继,删除 http://blog.csdn.net/feliciafay/article/details/12174307
- 带头结点单链表的基本操作(创建、测长、打印、插入、删除、取值、合并、排序、逆置)
- 链表的基本操作(插入,删除,排序、逆置等)
- C++链表的创建、插入、删除、查找、合并、排序、修改等操作的实现
- 编程菜鸟的日记-初学尝试编程-顺序表的类定义及其基本操作算法(创建表、元素插入、元素删除、顺序查找、测表空、求表长、输出等)
- 07单链表的一些基本操作(创建、测量、插入、打印、删除)
- ASP.NET对数据库的基本操作——插入,删除,修改(上)
- 栈的基本操作--插入,取栈顶元素,删除栈顶,清空栈
- 学习笔记——C语言实现单链表的基本操作:创建、输出、插入结点、删除结点、逆序链表
- 链表基本操作(建立、修改,插入、删除、打印)
- ASP.NET对数据库的基本操作——插入,删除,修改(下)
- 链表的基本操作(C语言版):建立,插入,删除,查找,输出
- 双向循环链表基本操作(初始化,插入,删除,清空,销毁,访问前驱,后继等)