数据结构3
树
树是n个节点的有限集合T,它满足了两个条件:有且仅有一个特定的称为根的节点;
其余的节点可以分为m(m>=0)个互不相交的有限集合T1,T2,,,,Tm,其中每一个集合有是一颗树,并称为其根的子树。
表示方法:树形表示法,目录表示法。
二叉树的性质
二叉树第i(i≥1)层上的节点最多为2i-1个。
深度为k(k≥1)的二叉树最多有2k-1个节点。
满二叉树 :深度为k(k≥1)时有2k-1个节点的二叉树。
完全二叉树 :只有最下面两层有度数小于2的节点,且最下面一层的叶节点集中在最左边的若干位置上。
具有n个节点的完全二叉树的深度为:(log2n)+1或(log2(n+1)。
二叉树的顺序存储结构
顺序存储结构 :完全二叉树节点的编号方法是从上到下,从左到右,根节点为1号节点。设完全二叉树的节点数为n,某节点编号为i;
当i > 1(不是根节点)时,有父节点,其编号为i / 2;
当2 * i ≤ n时,有左孩子,其编号为2 * i ,否则没有左孩子,本身是叶节点;
当2 * i+1 ≤ n时,有右孩子,其编号为2 * i + 1 ,否则没有右孩子;
当i为奇数且不为1时,有左兄弟,其编号为i - 1,否则没有左兄弟;
当i为偶数且小于n时,有右兄弟,其编号为i + 1,否则没有右兄弟;
二叉树的实现
二叉树是n个节点的有限集合,或者是空集(n=0),或者是有一个根节点以及两颗互不相交的,分别成为左子树和右子树的二叉树组成。
严格区分左孩子和右孩子,即使只有一个子节点也要分出左右节点。
二叉树结构体
typedef char data_t;
typedef struct node
{
data_t data;
struct node * left;
struct node * right
}tree,*treelink;
二叉树的创建
1.先建立根
2.建立左子树
3.建立右子树
treelink tree_ctrate()
{
data_t ch;
treelink R;
scanf("%c",&ch);
if(ch == '#')
{
return NULL;
}
if((R = (treelink)malloc(sizeof(tree))) == NULl)
{
pritnf("malloc failed\n");
return NULL;
}
R->data = ch;
R->left = tree_create();
R->right = tree_create();
return R;
}
二叉树的前序遍历
void tree_preorder(treelink R)
{
if(R == NULL)
{
return ;
}
printf("%c",r->data);
tree_preorder(R->left);
tree_preorder(R->right);
}
二叉树的中序遍历
void tree_inorder(treelink R)
{
if(R == NULL)
{
return ;
}
tree_preorder(R->left);
printf("%c",r->data);
tree_preorder(R->right);
}
二叉树的后序遍历
void tree_postorder(treelink R)
{
if(R == NULL)
{
return ;
}
tree_preorder(R->left);
tree_preorder(R->right);
printf("%c",r->data);
}
二叉树的层次遍历
void tree_layerorder(treelink * R)
{
queuelink lq;
if((R = queue_create()) == NULL)
return NULL;
if(R == NULL)
return ;
printf("%c",R->data);
queue_in(lq,R);
while(!queue_empty(lq))
{
R = queue_in(lq);
if(R->left)
{
printf("%c",R->left->data);
queue_in(lq,R->left);
}
if(R->right)
{
printf("%c",R->right->data);
queue(lq,R->right);
}
}
put("");
}
查找
哈希表
#ifdef __HASH_H__
#define __HASH_H__
#define N 15
typedef int data_t;
typedef struct node
{
data_t key;
data_t value;
struct node * next;
}listnode, *linklist;
typedef struct
{
listnode data[N];
}hash, *hashlink;
hashlink create();
int hash_insert(hashlink HT,data_t key);
#endif
哈希表的创建
hashlink create()
{
hashlink HT;
HT = (hashlink)malloc(sizeof(hash));
if(HT == NULL)
{
printf("malloc is failed/n");
return NULL;
}
memset(HT,0,sizeof(hash));
return HT;
}
哈希表的插入
int hash_insert(hash *HT,data_t key)
{
linklist p;
linklist q;
if(HT == NULL)
{
printf("HT is NULL\n");
return -1;
}
p = (linklist)malooc(sizeof(listnode));
if(p == NULL)
{
printf("malloc failed\n");
return -1;
}
p->key = key;
p->value = key % N;
p->next = NULL;
q = &(HT->data[key % N]);
while(q->next && q->next->key < p->key)
{
q = q->next;
}
p->next = q->next;
q->next = p;
return 0;
}
哈希表的查找
linklist hash_search(hashlink HT,data_t key)
{
linklist p;
if(HT == NULL)
{
printf("HT is NULL\n");
return -1;
}
p = &(HT ->data[key % N]);
while(p->next && p->next->key ! = key)
{
p = p->next;
}
if( p->next == NULL)
{
return NULL;
}
else
{
printf("found\n");
return p->next;
}
}
哈希表的平均查找长度
已知一个线性表(38,25,74,63,52,48),采用的散列函数为H(Key)=Key mod 7,将元素散列到表长为7的哈希表中存储。若采用线性探测的开放定址法解决冲突,则在该散列表上进行等概率成功查找的平均查找长度为?
线性探测法:
计算得:
H(38)=38%7=3;
H(25)=25%7=4;
H(74)=74%7=4;//与25冲突
H(74)=(4+1)%7=5;//哈希表的长度为7,5小于7
H(63)=63%7=0
H(52)=52%7=3;//与38冲突
H(52)=(3+1)%7=4;//与25冲突
H(52)=(3+2)%7=5;//与74冲突
H(52)=(3+3)%7=6;
H(48)=48%7=6;//与52冲突
H(48)=(6+1)%7=0;//与63冲突
H(48)=(6+2)%7=1;
value: | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
key: | 63 | 48 | 38 | 25 | 74 | 52 | |
次数: | 1 | 3 | 1 | 1 | 2 | 4 |
等概率查找长度为:(1+3+1+1+2+4)/6=2
链地址法:
H(38)=38%7=3;
H(25)=25%7=4;
H(74)=74%7=4;
H(63)=63%7=0;
H(52)=52%7=3;
H(48)=48%7=6;
等概率查找长度为:(1×4+2×2)/6=1.3
排序
排序分为:内排序和外排序。
内排序:插入排序(直接插入排序,折半插入排序,链表插入排序,shell(希尔)排序),交换排序,选择排序,归并排序。
快速排序
#include<stdio.h>
#include<stdlib.h>
#define N 15
int partion(int * data,int low,int high)
{
int temp = data[low];
while(low < high)
{
while(low < high && temp < = data[high])
high--;
data[low] = data[high];
while(low < high && temp > = data[high])
low++;
data[high] = data[low];
}
data[low] = temp;
return low;
}
int quink_sort(int * data,int low,int high)
{
int t;
if(data == NULL)
{
return -1;
}
if(low > = high)
{
return 0;
}
t = partion(data,low,high);
quick_sort(data,low,t-1);
quick_sort(data,t+1,high);
return 0;
}
int main(int argc,const char * argv[])
{
int data[N] = {0};
int i;
srandom(10);
for(i = 0;i < N;i++ )
{
data[i] = random() % 100;
}
for(i = 0;i < N;i++ )
{
printf("%d",data[i]);
}
puts("");
quink_sort(data,0,N-1);
for(i = 0;i < N;i++ )
{
printf("%d",data[i]);
}
puts("");
return 0;
}