二叉搜索树1—插入
在之前学习过链表,可以删除,搜索,插入数据,但是在链表中搜索元素的算法复杂度为O(n)。而使用动态树结构能更加有效地添加,删除和搜索数据。
搜索树是一种可以进行插入,搜索,删除等操作的数据结构。
二叉搜索树就是最基本的搜索树。二叉搜索树的各结点均有键值,且该树时常满足二叉搜索树的性质。
一个结点的左子树中的结点的键值小于等于该结点的键值,右子树中的结点的键值大于等于该结点的键值。
二叉搜索树的结点
struct node {
int key;
node* p, * l, * r;
};
在保证二叉树性质的前提下将给定的数据插入恰当位置。
void insert(int i) {
Node* x = root;
Node* y = nil;//x的父结点
Node* z = new Node;
z->data = i;
z->l = nil;
z->r = nil;
while (x != nil) {
y = x;
if (z->data < x->data) {
x = x->l;//移动至左子结点
}
else {
x = x->r;//移动至右子结点
}
}
z->p = y;
if (y == nil) {
root = z;
}
else {
if (z->data < y->data) {
y->l = z;//将z定为y的左子结点
}
else {
y->r = z;//将z定为y的右子结点
}
}
}
完整的代码如下:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
using namespace std;
struct node {
int key;
node* p, * l, * r;
};
node* root, * nil;
void insert(int k) {
node* y = nil;
node* x = root;
node* z;
z = new node;
z->key = k;
z->l = nil;
z->r = nil;
while (x != nil) {
y = x;
if (x->key > z->key) {
x = x->l;
}
else x = x->r;
}
z->p = y;
if (y == nil)root=z;
else if (z->key > y->key) {
y->r = z;
}
else y->l = z;
}
void inorder(node* u) {
if (u == nil)return;
inorder(u->l);
printf("%d ", u->key);
inorder(u->r);
}
void preorder(node* u) {
if (u == nil)return;
printf("%d ", u->key);
preorder(u->l);
preorder(u->r);
}
int main() {
int n, i, x;
string com;
scanf("%d", &n);
for (i = 0; i < n; i++) {
cin >> com;
if (com == "insert") {
scanf("%d", &x);
insert(x);
}
else if(com=="print"){
inorder(root);
printf("\n");
preorder(root);
printf("\n");
}
}
return 0;
}
当树高为h时,像二插搜索树中插入元素的操作的复杂度为O(h),如果数据足够平衡,算法复杂度为O()。但是在最坏的情况下,由于插入结点的键值和顺序的影响,树高可以接近结点数n,此时算法复杂度为O(n)。
读《挑战程序设计竞赛》第二十二天(侵删)2021.3.18
( 2021.7.12 第一次修改)