前言
Blog 好久没更新了,因为一方面忙着刷题,一方面搞大创(好浪费精力,不太想搞)
正文
今天突然不知道怎么回事,想看看之前买的数据结构书(挑战程序设计竞赛-算法和数据结构),
虽然整本书不太难,但是还是有很多不太明白的知识,光二叉搜索树就倒腾了一下午,怪我太菜了吧
BinarySearchTree
#include<bits/stdc++.h>
using namespace std;
struct node {
int key;
/*p是parent l是left r是right*/
node *p,*l,*r;
};
node *root;
//插入操作
void insert(int k) {
//y是要找的节点的父节点
node *y = NULL;
//x用来寻找应该插入的位置
node *x = root;
node *z = new node;
z->key = k;
z->l = NULL;
z->r = NULL;
while (x != NULL) {
y = x;
if( z->key < x->key)
x = x->l;
else
x = x->r;
}
z->p = y;
if(y == NULL)
root = z;
else {
if(z->key < y->key)
y->l = z;
else
y->r = z;
}
}
//查找操作
node* find(node *u,int k) {
while (u !=NULL && k != u->key) {
if(k < u->key)
u = u->l;
else u = u->r;
}
return u;
}
//寻找最左面的节点
node* TreeMin(node *x) {
while (x->l != NULL)
x = x->l;
return x;
}
//调用这个函数 就说明x下面肯定有右节点
node* TreeNext(node *x) {
if(x->r != NULL)
return TreeMin(x->r);
/*
node *y = x->p;
while (y!=NULL && x == y->r) {
x = y;
y = y->p;
}
return y;
*/
}
//删除操作 ***慢慢理解
void Delete(node *z) {
//y为要删除的对象 x为y子节点
node *y,*x;
//z没有或只有一个子节点
if(z->l == NULL || z->r ==NULL) y=z;
else y=TreeNext(z); //肯定有两个子节点
//确定y的子节点x
if(y->l != NULL) {
x = y->l;
}else x = y->r;
//删除y 就是 x 接到y的父节点上
if(x != NULL) {
x->p = y->p;
}
if(y->p == NULL) {
root = x;
}
else {
//把x接到y的父节点下
if(y == y->p->l)
y->p->l = x;
else
y->p->r = x;
}
if(y != z)
z->key = y->key;
free(y);
}
//中序遍历
void inorder(node *u) {
if(u == NULL) return;
inorder(u->l);
printf(" %d",u->key);
inorder(u->r);
}
//先序遍历
void preorder(node *u) {
if(u == NULL) 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 == "find") {
scanf("%d",&x);
node *f = find(root,x);
if(f != NULL)
puts("yes");
else
puts("no");
}else if(com == "delete") {
scanf("%d",&x);
Delete(find(root,x));
}
else if(com == "print") {
inorder(root); puts("");
preorder(root); puts("");
}
}
return 0;
}
二叉堆
最大堆: 结点的键值小于等于父节点的键值
最小堆: 结点的键值大于等于父节点的键值
#include<bits/stdc++.h>
using namespace std;
#define MAX 20000
int H,A[MAX+1];
void maxHeapify(int i)
{
int l,r,largest;
l= 2*i, r =2*i+1;
if(l<=H && A[l] > A[i])
largest = l;
else
largest = i;
if(r<=H && A[r] > A[largest]) largest = r;
if(largest != i)
{
swap(A[i],A[largest]);
maxHeapify(largest);
}
}
int main ()
{
cin >> H;
for(int i=1;i<=H;i++)
cin >> A[i];
for(int i=H/2; i>=1; i--)
maxHeapify(i);
for(int i=1; i<=H; i++)
cout <<" "<<A[i];
cout << endl;
return 0;
}
堆排序
#include<bits/stdc++.h>
using namespace std;
#define MAX 20000
int H,A[MAX+1];
void maxHeapify(int i,int len)
{
int l,r,largest;
l= 2*i+1, r =2*i+2;
if(l<len && A[l] > A[i])
largest = l;
else
largest = i;
if(r<len && A[r] > A[largest]) largest = r;
if(largest != i)
{
swap(A[i],A[largest]);
maxHeapify(largest,len);
}
}
void solve()
{
//先把最大值放到顶端
for(int i=H/2-1;i>=0;i--)
maxHeapify(i,H);
for(int i=0;i<H;i++){
cout <<" "<<A[i];
}cout<< endl;
//每次把最大的放到最后
for(int i=H-1;i>0;i--)
{
swap(A[0],A[i]);
maxHeapify(0,i);
}
for(int i=0;i<H;i++){
cout <<" "<<A[i];
}
cout << endl;
}
int main ()
{
cin >> H;
for(int i=0;i<H;i++)
cin >> A[i];
solve();
return 0;
}
排序总结
后记
下个月没什么特别多的事情,入门Java和Linux了,希望以后能用Java做题吧(熟悉一下Java,嘿嘿)