目录
二叉树各叶结点深度即递归层数。
链表查找第k个,快指针先走k个,再一起遍历知道快指针到链表尾。
二分查找注意循环推出条件low<=high。
二叉排序树中序遍历即升序排列顺序。
注意各类型逻辑熟练,其次考虑代码实现。
二叉树带权路径真题2014
//前序遍历,即先序遍历,即深度优先遍历
//deep代表路径长度
int WplPreOrder(BiTree p, int deep) {
static int wpl = 0;//静态局部变量和全局变量类似,只会初始化一次,区别是只在局部有效
if (NULL != p) {
//判断为叶结点是,将对应叶结点weight*deep,加到wpl
if (p->lchild == NULL && p->rchild == NULL)wpl += p->weight*deep;
// printf("%c", p->weight);
WplPreOrder(p->lchild, deep + 1);//递归左子树,路径长度+1
WplPreOrder(p->rchild, deep + 1);//递归右子树,路径长度+1
}
return wpl;
}
int WPL(BiTree tree) {
return WplPreOrder(tree, 0);
}
单链表查找倒数第k个真题2009
思路:
双指针。fast指针先走k个,随后fast指针和slow指针一同遍历,当fast指针指向NULL时,slow指针指向倒数第k个结点。
顺序查找
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef int ELemType;
typedef struct {
ELemType *elem;//整型指针,申请的堆空间的起始地址存入elem
int TableLen;//存储动态数组里面元素的个数
} SSTable;
void STInit(SSTable &ST, int len) {
//多申请一个位置,存放哨兵,不使用哨兵也可以
ST.TableLen = len + 1;
ST.elem = (ELemType *) malloc(sizeof(ELemType) * ST.TableLen);
srand(time(NULL));//随机数生成
for (int i = 1; i < ST.TableLen; i++) {//因为第0个是哨兵,所以从1随机
ST.elem[i] = rand() % 100;//为了随机生成的数据都在1到99之间
}
}
int SearchSeq(SSTable ST, ELemType key) {
ST.elem[0] = key;//key存在零号元素作为哨兵,不用在for loop中判断i>=0
int i = ST.TableLen - 1;
for (; ST.elem[i] != key; i--);//从后往前找,找到就跳出循环,i刚好是对应的位置
return i;
}
void STPrint(SSTable ST) {
for (int i = 1; i < ST.TableLen; i++) {
printf("%3d", ST.elem[i]);
}
printf("\n");
}
int main() {
SSTable ST;
STInit(ST, 10);
STPrint(ST);//打印顺序表中元素
ELemType key;
printf("please input search key:\n");
scanf("%d", &key);
int pos;
pos = SearchSeq(ST, key);
if (pos)printf("find key,pos=%d\n", pos);
else printf("unfond\n");
return 0;
}
折半查找
折半查找又称二分查找,仅适用于有序的顺序表。
将查找值key与表中间位置的原元素比较,若相等则查找成功,返回该元素的存储位置;若不等,则所需查找的元素在中间元素以外的前半部分或后半部分继续查找,知道找到为止,或确定找不到。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef int ElemType;
typedef struct {
ElemType *elem;//整形指针
int TableLen;//存储动态数组里面的元素个数
} SSTable;
void InitST(SSTable &T, int len) {
T.TableLen = len;
T.elem = (ElemType *) malloc(sizeof(ElemType) * T.TableLen);
srand(time(NULL));//随机数生成
for (int i = 0; i < T.TableLen; i++) {
T.elem[i] = rand() % 100;
}
}
void PrintST(SSTable T) {
for (int i = 0; i < T.TableLen; i++) {
printf("%3d", T.elem[i]);
}
printf("\n");
}
int BinarySearch(SSTable L, ElemType key) {
int low = 0;
int high = L.TableLen - 1;
int mid;
while (low <= high) {//low<=high可以让mid既能取到low也能取到high
mid = (low + high) / 2;
if (key > L.elem[mid]) low = mid + 1;
else if (key < L.elem[mid]) high = mid - 1;
else return mid+1;
}
return 0;
}
//函数名中存储的是函数的入口地址,也是一个指针,是函数指针类型
//left和right指向元组中任意两个元素
//qsort规定,若left指向的值大于right指向的值返回正值,小于返回负值,等于返回0
int compare(const void *left, const void *right) {
return *(ElemType *) left - *(ElemType *) right;
//return *(ElemType *)right-*(ElemType *)left;//从大到小排序
}
int main() {
SSTable T;
InitST(T, 10);//初始化,随机生成10个元素
PrintST(T);
qsort(T.elem, T.TableLen, sizeof(ElemType), compare);//排序
PrintST(T);
ElemType key;
printf("please input search key:\n");
scanf("%d", &key);
int pos = BinarySearch(T, key);
if (0==pos)printf("unfind\n");
else printf("find key %d\n", pos);
return 0;
}
二叉排序树
二叉排序树(也称二叉查找树),或者是一颗空树,是具有下列特征的二叉树。
- 若左子树非空,则左子树上的所有结点的值均小于根结点的值。
- 作右子树非空,则右子树上的所有结点的值均大于根节点的值。
- 左、右子树也分别是一颗二叉排序树,1、2特征对所有结点适用。
二叉树的最大查找次数是树的高度。
#include <stdio.h>
#include <stdlib.h>
typedef int KeyType;
typedef struct BSTNode {
KeyType key;
struct BSTNode *lchild, *rchild;
} BSTNode, *BiTree;
//递归创建二叉查找树
int InsertRecuBST(BiTree &T, KeyType k) {
if (NULL == T) {
//为新结点申请空间,第一个结点作为树根,后面递归在进入就不是树根,是为叶子结点
T = (BiTree) malloc(sizeof(BSTNode));
T->key = k;
T->lchild = T->rchild = NULL;
return 1;//代表插入成功
} else if (k == T->key) return 0;//发现相同元素不插入
else if (k < T->key)//若插入结点小于当前结点
//函数调用结束后,左孩子和原来的父结点关联起来,巧妙利用了引用机制
return InsertRecuBST(T->lchild, k);
else
return InsertRecuBST(T->rchild, k);
}
//非递归创建二叉查找树
int InsertBST(BiTree &T, KeyType k) {
//新结点申请空间
BiTree newTree = (BiTree) calloc(1, sizeof(BSTNode));
newTree->key = k;
if (NULL == T) {
T = newTree;
return 1;
}
BiTree p = T, parent;//用来查找树
//while loop查找叶子节点
while (p) {
parent = p;//parent存放父结点
if (k > p->key) {
p = p->rchild;
} else if (k < p->key) {
p = p->lchild;
} else {
return 0;//相等元素不能放入查找树,考研不考虑相等元素存放
}
}
//接下来判断放到父结点左边还是右边
//成为父结点的右孩子
if (k > parent->key)parent->rchild = newTree;
//成为父结点的左孩子
else parent->lchild = newTree;
return 1;
}
//树中不放相等元素
void CreateBST(BiTree &T, KeyType *str, int len) {
for (int i = 0; i < len; i++) {
InsertBST(T, str[i]);
}
}
void MidOrder(BiTree T) {
if (T != NULL) {
MidOrder(T->lchild);
printf("%3d", T->key);
MidOrder(T->rchild);
}
}
BiTree SearchBST(BiTree T, KeyType k, BiTree &parent) {
parent = NULL;//防止空树,需要先赋值NULL
while (T != NULL && k != T->key) {
parent = T;
if (k > T->key) T = T->rchild;
else T = T->lchild;
}
return T;
}
int main() {
BiTree T = NULL;//树根
KeyType str[7] = {54, 20, 66, 40, 28, 79, 58};
CreateBST(T, str, 7);
MidOrder(T);//中序遍历二叉查找树是由小到大的
printf("\n");
BiTree search, parent;
search = SearchBST(T, 40, parent);
if (search) printf("find key %d", search->key);
else printf("unfind");
return 0;
}