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

来源:互联网 发布:移动宽带网络客服电话 编辑:程序博客网 时间:2024/06/10 20:08

一、线性查找

基本思想:对给定的一关键字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 10typedef 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;elselow = 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);elsep = 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;elsep = 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);elseprintf("\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);}
持续更新中~~



1 0
原创粉丝点击