您的位置:首页 > 理论基础 > 数据结构算法

C语言基本数据结构之四(线性,对分,二叉树查找及二叉树删除)

2016-12-24 17:09 309 查看

一、线性查找

基本思想:对给定的一关键字K,从线性表的一端开始,逐个进行记录的关键字和 K 的比较,直到找到关键字等于 K 的记录(成功)或到达表的另一端(失败),其时间复杂度为O(n)。

查找成功时的平均查找次数为:

ASL=(1+2+3+4+……+n)/n=(n+1)/2

查找不成功时的比较次数为:n+1

优点:算法简单,无需排序,采用顺序和链式存储均可。

缺点:平均查找长度较大。

二、对分查找

基本思想:对有序文件,进行查找,先找“中间记录”,进行比较,根据不同情况,逐步缩小范围,直到找到或确认找不到该记录为止。
适用条件:必须在具有顺序存储结构的有序表中进行。其时间复杂度为O(log2 (n))
优点:相对线性查找方式,对分查找次数要少,查找速度快。
缺点:要求表中的记录是按关键字排序,并且只适用于线性存储结构,当n较小的时候,其效果不十分显著

三、二叉排序树

3.1二叉排序树或者是一棵空树;或者是具有如下特性的二叉树:

(1)若它的左子树不空,则左子树上所有结点的值均小于根结点的值;
(2)若它的右子树不空,则右子树上所有结点的值均大于根结点的值;
(3)它的左、右子树也都分别是二叉排序树。

3.2删除二叉树节点

1. 如果被删除的是叶子结点,则删除后不影响整个树的结构;

2. 若被删结点只有左子树或右子树,只要将其左子树或右子树直接成为其双亲结点的左或右子树即可;

3. 若被删结点P的左右子树都非空,这时要循着P的左子树的根结点C向右一直找到结点S,要求S的右子树为空,然后将S的左子树改为结点Q的右子树,将S结点的数据域取代P结点的数据域值。

四、代码解析

直接贴上~~~
#include<stdio.h>
#include<malloc.h>
#define MAX 10
typedef struct STable stable;
typedef struct BTNode Node;
struct STable{
int key;
int other;
};
/*二叉树的节点类型*/
struct BTNode{
int data;
Node *Lchild;
Node *Rchild;
};

stable table[MAX];
/*
线性查找
*/
int search(stable s[],int key,int size){
int i = size;
s[0].key = key;/*设置监视哨,以控制比较次数 ,在size 很大的情况下可以节省几乎一半的时间*/
while(s[i].key !=key)
i--;    /* 由表尾向前查找*/
return (i);
}
/*对分查找,按升序排列
*/
int HalfSearch(stable s[],int key,int size){
int low ,hight ,mid;
low = 1;
hight = size;
while(low <= hight){
mid = (low + hight)/2;
if(s[mid].key == key){
return (mid);
}
else if(s[mid].key > key)
hight = mid - 1;
else
low = mid + 1;
}
return (0) ;
}
/*二叉排序树的插入*/
Node *insertBT(Node *t,int key){
if(NULL==t){
t = (Node * )malloc(sizeof(Node));
t->Lchild = NULL;
t->Rchild = NULL;
t->data = key;
}
else if(key < t->data){
t->Lchild = insertBT(t->Lchild,key);
}
else{
t->Rchild = insertBT(t->Rchild,key);
}

return (t);
}
/* 二叉排序树的查询,返回该点的Node*/
Node *BTSearch(Node *t,int key){
Node *p = NULL;
if(NULL!=t){
if(t->data ==key)
p = t;
else if(key < t->data)
p = BTSearch(t->Lchild,key);
else
p = BTSearch(t->Rchild,key);
}
return (p);
}
/*删除key节点*/
int DeleteNode(Node *t,int key){
int flag = 0;
Node *s,*q,*p,*f;/* f 是p 的父节点,s 是指向比key节点稍小的节点*/
p = t;
f = NULL;
/*查找到该Key所在的节点*/
while(p){
if(key != p->data){
f = p;
if(key < p->data)
p = p->Lchild;
else
p = p->Rchild;
}
else if(key == p->data)
break;
}
/*如果不存在*/
if(NULL==p){
printf(" 无此点");
return flag;
}
if(NULL==p->Lchild)
s = p->Rchild;
else if(NULL==p->Rchild)
s = p->Lchild;
else
{
/* p节点有两个子节点的情况*/
q = p;
s = p->Lchild;
/*找到比p节点稍小的节点,以便于替换p*/
while(NULL !=s->Rchild){
s = s->Rchild;
}
/* 如果p的左孩子的右孩子为null*/
if (q == p)
q->Lchild = s->Lchild;
else q->Rchild = s->Lchild;
p->data = s->data; /*将s节点替换掉p*/
free(s);
flag = 1;
}
/*p 点只有一个孩子节点*/
if ( flag == 0) {
if  ( f == NULL) //p节点的父节点为NULL 即P为树的根节点
t = s;
else if  (f->Lchild == p)
f->Lchild = s;
else f->Rchild = s;
free(p);
}
return (flag);
}
/*
判断该点是否为null
*/
void showNode(Node *q){
if(NULL!=q)
printf("\nYes the  data is %d \n",q->data);
else
printf("\n fail to search \n");
}
void main(){
int i,n;
Node *t=NULL,*q;
/*初始化数据*/
for(i = 1;i<=MAX;i++){
table[i].key = i + 10 ;
}
/*线性查找*/
n = search(table,13,MAX);
printf("\n search position is %d \n",n);
n = 0;
/*对分查找*/
n = HalfSearch(table,17,MAX);
printf("\n HalfSearch position is %d \n",n);
i = 1;
/*初始化二叉排序树*/
while(i<=MAX){
t = insertBT(t,table[i].key);
i++;
}
/*二叉排序树查找*/
q = BTSearch(t,12);
showNode(q);
/*删除该数*/
DeleteNode(t,12);
printf("\n still exist 12 ? \n");
q = BTSearch(t,12);
showNode(q);
}
持续更新中~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐