二叉搜索樹(Binary Searching Tree)
記住的特點就是左邊的key<=根的key 右邊的key>=根的key
定義:支持多種動態集合操作,插入、刪除、找最小值、最大值、前驅、後繼、查找。
用途:即可做字典,也可以做優先隊列。
時間複雜度:基本操作時間和樹的高度成正比。對於n個節點的完全二叉樹,最壞運行時間O(lgn).如果樹是含n個節點 線性鏈,則最壞操作時間是o(n)。平均時間O(lgn)。
STL中的map容器就是使用的這個。
數據結構
struct node
{
int _id;
char _value;
struct node* l_node;
struct node* r_node;
};
插入結點
#include <stdio.h>
#include <stdlib.h>
typedef struct _Node
{
unsigned _key;
char _value;
struct _Node * _left;
struct _Node * _right;
} Node, *PNode;
PNode make_node(unsigned key, char value);
PNode insert_node(PNode root, PNode node);
PNode header = NULL;
int main(int ac, char * av[])
{
PNode root = NULL;
PNode node = make_node(5, 'a');
root = insert_node(root, node);
node = make_node(3, 'b');
root = insert_node(root, node);
node = make_node(6, 'c');
root = insert_node(root, node);
return 0;
}
PNode make_node(unsigned key, char value)
{
PNode node = (PNode)(malloc(sizeof(Node)));
if (node)
{
node->_key = key;
node->_value = value;
node->_left = NULL;
node->_right = NULL;
}
return node;
}
PNode insert_node(PNode root, PNode node)
{
if (!root)
{
return node;
}
if (root->_key == node->_key)
{
root->_value = node->_value;
}
else if (root->_key > node->_key)
{
root->_left = insert_node(root->_left, node);
}
else
{
root->_right = insert_node(root->_right, node);
}
return root;
}
刪除結點
分四種情況討論:
- 要刪除的結點是葉子結點,則直接刪除
- 要刪除的結點是中間某個結點,有右子節點
- 有左子節點,與2情況想同,但是代碼不同
- 有左右子節點,找左側最大或者右側最小的替換他,是他變成葉子結點,然後刪掉。
#include <stdio.h>
#include <stdlib.h>
typedef struct _Node
{
unsigned _key;
char _value;
struct _Node * _left;
struct _Node * _right;
} Node, *PNode;
PNode make_node(unsigned key, char value);
PNode insert_node(PNode root, PNode node);
PNode find_max(PNode root);
void exchange(PNode node1, PNode node2);
PNode process_remove(PNode root, bool * is_exchange);
PNode remove_node(PNode root, unsigned key);
PNode header = NULL;
int main(int ac, char * av[])
{
PNode root = NULL;
PNode node = make_node(5, 'a');
root = insert_node(root, node);
node = make_node(3, 'b');
root = insert_node(root, node);
node = make_node(6, 'c');
root = insert_node(root, node);
root = remove_node(root, 6u);
return 0;
}
PNode make_node(unsigned key, char value)
{
PNode node = (PNode)(malloc(sizeof(Node)));
if (node)
{
node->_key = key;
node->_value = value;
node->_left = NULL;
node->_right = NULL;
}
return node;
}
PNode insert_node(PNode root, PNode node)
{
if (!root)
{
return node;
}
if (root->_key == node->_key)
{
root->_value = node->_value;
}
else if (root->_key > node->_key)
{
root->_left = insert_node(root->_left, node);
}
else
{
root->_right = insert_node(root->_right, node);
}
return root;
}
PNode find_max(PNode root)
{
PNode temp = root;
while (temp->_right)
{
temp = temp->_right;
}
return temp;
}
void exchange(PNode node1, PNode node2)
{
unsigned key = node1->_key;
char value = node1->_value;
node1->_key = node2->_key;
node1->_value = node2->_value;
node2->_key = key;
node2->_value = value;
}
PNode process_remove(PNode root, bool * is_exchange)
{
bool has_left = root->_left, has_right = root->_right;
PNode node = NULL;
if (!has_left && !has_right)
{
free(root);
node = NULL;
}
else if (has_left && !has_right || has_right && !has_left)
{
if (has_left && !has_right)
{
node = root->_left;
free(root);
root = NULL;
}
else
{
node = root->_right;
free(root);
root = NULL;
}
}
else
{
PNode max_node = find_max(root->_left);
exchange(max_node, root);
*is_exchange = true;
}
*is_exchange = false;
return node;
}
PNode remove_node(PNode root, unsigned key)
{
bool is_exchanged = false;
if (root == NULL)
{
return NULL;
}
if (root->_key == key)
{
root = process_remove(root, &is_exchanged);
/*如果沒交換*/
if (!is_exchanged)
{
return root;
}
}
if (root->_key > key || is_exchanged)
{
root->_left = remove_node(root->_left, key);
}
else if (root->_key < key)
{
root->_right = remove_node(root->_right, key);
}
return root;
}
深度優先遍歷
#include <stdio.h>
#include <stdlib.h>
typedef struct _Node
{
unsigned _key;
char _value;
struct _Node * _left;
struct _Node * _right;
} Node, *PNode;
PNode make_node(unsigned key, char value);
PNode insert_node(PNode root, PNode node);
void visit_node(PNode node);
void pre_order(PNode root);
void post_order(PNode root);
void in_order(PNode root);
PNode header = NULL;
int main(int ac, char * av[])
{
PNode root = NULL;
PNode node = make_node(5, 'a');
root = insert_node(root, node);
node = make_node(3, 'b');
root = insert_node(root, node);
node = make_node(6, 'c');
root = insert_node(root, node);
node = make_node(2, 'd');
root = insert_node(root, node);
node = make_node(4, 'e');
root = insert_node(root, node);
node = make_node(7, 'f');
root = insert_node(root, node);
in_order(root);
return 0;
}
PNode make_node(unsigned key, char value)
{
PNode node = (PNode)(malloc(sizeof(Node)));
if (node)
{
node->_key = key;
node->_value = value;
node->_left = NULL;
node->_right = NULL;
}
return node;
}
PNode insert_node(PNode root, PNode node)
{
if (!root)
{
return node;
}
if (root->_key == node->_key)
{
root->_value = node->_value;
}
else if (root->_key > node->_key)
{
root->_left = insert_node(root->_left, node);
}
else
{
root->_right = insert_node(root->_right, node);
}
return root;
}
void visit_node(PNode node)
{
if (!node)
return;
printf("%c\n", node->_value);
}
/*DFS 前序遍歷*/
void pre_order(PNode root)
{
//終止條件
if (!root)
return;
/*訪問根節點*/
visit_node(root);
//遍歷左子樹
pre_order(root->_left);
//遍歷右子樹
pre_order(root->_right);
}
/*DFS 後序遍歷*/
void post_order(PNode root)
{
/*終止條件*/
if (!root)
return;
/*遍歷左子樹*/
post_order(root->_left);
/*遍歷右子樹*/
post_order(root->_right);
/*訪問根節點*/
visit_node(root);
}
/*DFS中序遍歷*/
void in_order(PNode root)
{
/*終止條件*/
if (!root)
return;
/*遍歷左子樹*/
in_order(root->_left);
/*訪問根節點*/
visit_node(root);
/*遍歷右子樹*/
in_order(root->_right);
}
廣度優先遍歷
#include <stdio.h>
#include <stdlib.h>
typedef struct _Node
{
unsigned _key;
char _value;
struct _Node * _left;
struct _Node * _right;
} Node, *PNode;
typedef struct _QueueNode
{
struct _QueueNode * next;
PNode value;
} QueueNode, *PQueueNode;
PQueueNode queue_header = NULL;
void push(PQueueNode queue_node)
{
if (!queue_node)
{
return;
}
if (!queue_header)
{
queue_header = queue_node;
return;
}
PQueueNode next_node = queue_header;
while (next_node->next)
{
next_node = next_node->next;
}
next_node->next = queue_node;
}
PQueueNode pop(void)
{
if (!queue_header)
{
return NULL;
}
PQueueNode node = queue_header;
queue_header = queue_header->next;
return node;
}
PQueueNode make_queue_node(PNode value)
{
if (!value)
{
return NULL;
}
PQueueNode node = (PQueueNode)(malloc(sizeof(QueueNode)));
node->next = NULL;
node->value = value;
return node;
}
bool has_next(void)
{
return queue_header;
}
PNode make_node(unsigned key,char value)
{
PNode node = (PNode)(malloc(sizeof(Node)));
if (node)
{
node->_key = key;
node->_value = value;
node->_left = NULL;
node->_right = NULL;
}
return node;
}
PNode insert_node(PNode root, PNode node)
{
if (!root)
{
return node;
}
if (root->_key==node->_key)
{
root->_value = node->_value;
}
else if (root->_key>node->_key)
{
root->_left = insert_node(root->_left, node);
}
else
{
root->_right = insert_node(root->_right, node);
}
return root;
}
void visit_node(PNode node)
{
if (!node)
return;
printf("%c\n", node->_value);
}
void visit_BFS(PNode root)
{
if (!root)
{
return;
}
push(make_queue_node(root));
while (has_next())
{
PQueueNode queue_node = pop();
PNode tree_node = queue_node->value;
visit_node(tree_node);
push(make_queue_node(tree_node->_left));
push(make_queue_node(tree_node->_right));
free(queue_node);
queue_node = NULL;
}
}
int main(void)
{
PNode root = NULL;
PNode node = make_node(5, 'a');
root = insert_node(root, node);
node = make_node(3, 'b');
root = insert_node(root, node);
node = make_node(6, 'c');
root = insert_node(root, node);
node = make_node(2, 'd');
root = insert_node(root, node);
node = make_node(4, 'e');
root = insert_node(root, node);
node = make_node(7, 'f');
root = insert_node(root, node);
visit_BFS(root);
return 0;
}