快排和红黑树
Posted 灰极客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快排和红黑树相关的知识,希望对你有一定的参考价值。
快排
//partition function
int partition(int data[], int length, int start, int end) {
if (length <= 0 || start < 0|| end >= length || data == NULL)
return -1;
int index = random(start,end);// ramdom select the index of data;
swap(&data[index], &data[end]);
int small = start - 1;// small num is smaller than data[end]
for (index = start; index <= end; index++) {
if (data[index] < data[end]) {
small++;
swap(&data[index],&data[small]);
}
}
small++;
swap(&data[small],&data[end]);
return small;
}
//quicksort
void quicksort(int data[], int length, int start, int end) {
if (data == NULL || length <= 0|| start < 0|| end >= length)
return;
int index = partition(data,length,start,end);
if (index > start)
quicksort(data, length, start, index-1);
if (index < end)
quicksort(data, length,index+1, end);
}
//红黑树
红黑树五大特点:
1、每个节点是红色或黑色
2、根节点是黑色
3、每个叶子结点是黑色,叶子结点指为空的nil节点,如图
4、每个红色节点的两个子节点都是黑色的
5、任意一个节点到其每个叶子结点的所有路径上包含的黑节点数相等
code achieve:
struct node * {
enum {red, black} color;
int key; //each node data
struct node *left, *right, *parent;
};
//some operations
struct node *parent(struct node *n) {
if (node != NULL) {
return n->parent;
}
return NULL;
}
struct node *grandparent(struct node * n) {
if (n != NULL) {
struct node *parent_node = parent(n);
if (parent_node == NULL)
return NULL;
return parent(parent_node);
}
retun NULL;
}
struct node * uncle (struct node * n) {
if (n == NULL)
return NULL;
struct node *parent_node = parent(n);
struct node * grandparent_node = grandparent(n);
if (grandparant_node == NULL)
return NULL;
if(grandparent->left == parent_node)
return grandparen->right;
else
retun grandparent->left;
}
struct node * brother(struct node * n) {
if(n == NULL)
return NULL;
struct node * parent_node = parent(n);
if (parent_node == NULL)
return NULL;
if (parent->left == n)
return parent->right;
else
return parent->left;
}
int node_is_parent_left_or_right(struct node *n) {
struct node * parent = paren(n);
if (NULL == parent)
return 0;
if (parent->left == n)
return 1;
else
return 2;
}
void left_rotate(struct node *n) {
if (n == NULL || n->right == nil) //nil为空的叶子结点
return;
int index = node_is_parent_left_or_right(n);
struct node *temp = n->right;
n->right = temp->left;
temp->left = n;
temp->parent = n->parent;
n->parent = temp;
if (index == 1)
temp->parent->left = temp;
else if(index == 2)
temp->parent->right = temp;
}
void right_rotate(struct node *n) {
if (n == NULL || n->left == nil)
return;
int index = node_is_parent_left_or_right(n);
struct node *temp = n->left;
n->left = temp->right;
temp->right = n;
temp->parent = n->parent;
n->parent = temp;
if (index == 1)
temp->parent->left = temp;
elss if (index == 2)
temp->parent->right = temp;
}
//insert node
struct node *insert(struct node *root, struct node * node) {
//insert new node into tree
insert_recurse(root,node);
//repair case (five feature)
insert_repair_tree(node);
root = node;
while(parent(root) != NULL)
root = parent(root);
return root;
}
void insert_recurse(struct node *root, struct node *n){
if (root != NULL && n->key < root->key) {
if (root->left != nil) {//nil is leaf node
insert_recurse(root->left,n);
return;
} else
root->left = n;
} else if (root != NULL) {
if (root->right != nil) {
insert_recurse(root->right,n);
return;
} else
root->right = n;
}
//maybe root == NULL
n->parent = root;
n->left = nil; //leaf node is different from NULL
n->right= nil;
n->color = red; //red is convenient to repair
}
void insert_repair_tree(struct node *n) {
//four cases
if (parent(n) == NULL) { //n is root node
insert_case1(n);
} else if (parent(n)->color == black) { // nothing to do
insert_case2(n);
} else if (uncle(n)->color == red) {
insert_case3(n);
} else { //parent(n)->color == red || uncle(n)->color == black
insert_case4(n);
}
}
void insert_case1(struct node *n) {
if (parent(n) == NULL)
n->color = black;
}
void insert_case2(struct node *n){
return;
}
//insert_case3
void insert_case3(struct node *n) {
//N is n
parent(n)->color = black;
uncle(n)->color = black;
grandparent(n)->color = red; //feature 4 and 5
insert_repair_tree(grandparent(n));
}
//insert_case4
void insert_case4(struct node *n) {
struct node *p = parent(n);
struct node *g = grandparent(n);
if (g->left->right == n) {
left_rotate(p);
n = n->left; //更新n
} else if (g->right->left == n ) {
right_rotate(p);
n = n->right;
}
insert_case4nextstep(n);
}
// insert_case next step
void insert_case4nextstep(struct node *n) {
struct node * g = grandparent(n);
struct node *p = parent(n);
if (p->left == n) {
right_rotate(g);
} else if (p->right == n) {
left_rotate(g);
}
p->color = black;
g->color = red;
}
//delete node
void replace_node(struct node *n, struct node *child, strucy node *root,struch node *root) { //n is replace to child
child->parent = n->parent;
if (n->parent == NULL) {
root = child
return;
}
if(n->parent->left == n)
n->parent ->left = child;
else
n->parent->right = child;
}
void delete_one_child(struct node *n) {
//n has at most one non-leaf child.maximum in left subtree or minimum in right subtree.
struct node *child = is_leaf(n->left) ? n->right:n->left;
replace_node(n,child);
if (n->color == black) {//free black is concern feature 4 and 5
if (child->color == red)
child->color = black;
else {
delete_case1(child);
}
}
free(n);
}
void delete_case1(struct node *n) {
if (n->parent != NULL)
delete_case2(n);
}
//delete case2
void delete_case2(struct node *n) {
struct node *s = brother(n);
if (s->color == red) {
n->parent->color = red;
s->color = black;
if (n == n->parent->left)
left_rotate(n->parent);
if (n == n->parent->right)
right_rorate(n->parent);
}
delete_case3(n);
}
//delet case 3
void delete_case3(struct node *n) {
struct node * s = brother(n);
if ((n->paren->color == black) &&(s->color == black) && (s->left->color == black) && (s->right->color = black)) //如上图
s->color = red;
delete_case1(n->parent);
} else
delete_case4(n);
}
//delet case 4
void delet_case4(struct node *n) {
struct node * s = brother(n);
if ((n->color ==black) && (n->parent->color == red) && (s->color==black)&&(s->left->color ==black)&&(s->right->color==black) ) {
n->parent->color = black;
s->color = red;
} else {
delete_case5(n);
}
}
//delete case 5
void delete_case5(struct node* n) {
struct s = brother(n);
if (s->color == black) {
if ((n==n->parent->left)&&(s->right->color==black)&&(s->left->color==red)) {
s->color=red;
s->left-color=black;
right_rorate(s);
}else if ((n==n->parent->right)&&(s->right->color==red)&&(s->left->color==black)) {
s->color = red;
s->right->color=black;
left_rorate(s);
}
}
delete_case6(n);
}
//delete case 6
void delete_case6(struct node *n) {
struct node *s = brother(n);
s->color = s->parent->color;
n->parent->color = black;
if (n == n->parent->left) { //上图
s->right->color = black;
left_rorate(n->parent);
} else {
s->left->color = black;
right_rorate(n->parent);
}
}
以上是关于快排和红黑树的主要内容,如果未能解决你的问题,请参考以下文章