查找的相关操作总结

来源:互联网 发布:淘宝买快排犯法吗 编辑:程序博客网 时间:2024/05/22 10:40

操作包含

  1. 递归折半查找
  2. 非递归折半查找
  3. 二叉排序树的建立、查找、删除、插入
  4. 哈希表的建立和输出
  5. 判断一个二叉树是不是平衡二叉树

#include<stdio.h>#include<stdlib.h>#include<string.h>#define MAX_SIZE 100int nums1[] = {5,7,3,2,9,4,8,1,10,6};int nums2[] = {1,2,3,4,5,6,7,8,9,10};int nums3[] = {51,24,23,4,57,69,70,18,9,10};typedef struct BiNode{int data;struct BiNode *lchild;struct BiNode *rchild;}BiNode;void printData(int i){printf("The index of the num is %d",i);}void printData2(int i){printf("%d ",i);}void printInfo(char *s){printf("%s",s);}//递归折半查找int binSearch(int low,int high ,int i){if (low > high){return -1;}int mid = (low + high)/2;if (nums2[mid] < i){low = mid + 1;return binSearch(low,high,i);} else if (nums2[mid] > i){high = mid -1;return binSearch(low,high,i);}else {return mid;}}//非递归折半查找//时间复杂度O(log2n)void binSearch2(int i){int low = 0,high = 9;int mid;while(low <= high){mid = (low + high)/2;if (nums2[mid] < i){low = mid + 1;} else if (nums2[mid] > i){high = mid -1;}else {printData(mid);break;}}}/****************************************二叉排序树的操作开始**********************************************/BiNode* mallocNewNode(int data){BiNode * root ;root = (BiNode*)malloc(sizeof(BiNode));root->data = data;root->rchild = NULL;root->lchild = NULL;return root;}//创建二叉排序树BiNode* createBST(){int i = 1,data;int flag;BiNode * root ,*p,*pre;root = mallocNewNode(nums1[0]);p = root;for (i = 1; i< 10;i++){data = nums1[i];p = root;//直到p为空为止,这时证明p已经处于叶子结点。while(p != NULL){if (p->data < data){pre = p;flag = 1;p = p->rchild;} else if (p->data > data){pre = p;flag = 2;p = p->lchild;} else {//存在相同元素continue;}}p = mallocNewNode(data);if (flag == 1){pre ->rchild = p;} else {pre ->lchild = p;}}return root;}//递归插入二叉排序树,非递归见上面的创建void insertBST(BiNode ** p,int data){if ((*p) == NULL){(*p) = mallocNewNode(data);return;} else if ((*p)->data < data){insertBST(&((*p)->rchild),data);} else if ((*p)->data > data){insertBST(&((*p)->lchild),data);} else {return;}}void searchBST(BiNode* root, int data){BiNode* p = root;while(p != NULL){if (p->data < data){p = p->rchild;} else if (p->data > data){p = p->lchild;} else {printInfo("找到指定元素!\n");break;}}if (p == NULL){printInfo("没有找到指定元素!\n");}}//删除二叉排序树中的元素void deleteBST(BiNode **root,int data){ //首先找到指定结点。。 BiNode *p = *root; BiNode *pre = NULL; BiNode *temp = NULL; BiNode *temppre = NULL; int flag = 0; while(p != NULL){ if (p->data < data){ flag = 1;//右子树 pre = p; p = p->rchild; } else if (p->data > data){ flag = 2;//左子树 pre = p; p = p->lchild; } else { break; } } if (p == NULL){ printInfo("没有指定结点,无法执行删除操作\n"); return ; }   if (p ->lchild == NULL && p->rchild == NULL){//本身是叶子节点,删除本身即可。 if (flag == 1){ pre ->rchild = NULL; } else { pre ->lchild = NULL; } free(p); } else if ((p->rchild != NULL && p->lchild == NULL) || (p->rchild == NULL && p->lchild != NULL)){ //左或右子树不为空,则其值为左或者右子树 temp = p->rchild != NULL? p->rchild : p->lchild; if (flag == 1){ pre ->rchild = temp; } else { pre ->lchild = temp; }free(p);  } else { //直接前驱或者直接后继。右子树的最左侧或者左子树的最右侧 temp = p ->lchild; pre = p; while(temp != NULL){ pre = temp; temp = temp->rchild; }//temp 此时为空。将P结点替换为左子树的最右侧结点 p->data = pre ->data; //删除左子树的最右侧结点 temp = p ->lchild; temppre = p; while(temp != pre){ temppre = temp; temp = temp->rchild; } if (temppre == p){ temppre ->lchild = pre->lchild; free(pre); } else { temppre ->rchild = pre->lchild; free(pre); }   }}//前序非递归遍历void preOrderTraverse(BiNode* root){BiNode * stack[MAX_SIZE];int top = -1;BiNode * p = root;while(p != NULL || top > -1){if ( p != NULL){printData2(p->data);stack[++top] = p;p = p->lchild;} else {p = stack[top--];p = p->rchild;}}}//中序非递归遍历void inOrderTraverse(BiNode* root){BiNode * stack[MAX_SIZE];int top = -1;BiNode * p = root;while(p != NULL || top > -1){while ( p != NULL){stack[++top] = p;p = p->lchild;}p = stack[top--];printData2(p->data);p = p->rchild;}}//后序非递归遍历void postOrderTraverse(BiNode* root){BiNode * stack[MAX_SIZE];int top = -1;BiNode * p = root,* pre;stack[++top] = p;  p = p->lchild;  while(top > -1){while (p != NULL){stack[++top] = p;p = p->lchild;}pre = NULL;//为什么要循环,因为有可能在栈中多个结点的右子树已经访问过了,//已经具备了输出的条件while (top > -1){p = stack[top];//其右子树访问过后,再访问根节点if (p->rchild == pre){printData2(p->data);top--;//出栈pre = p;} else {//因为右子树还没访问,所以不能出栈,要停止循环,向右走一步之后向左走p = p->rchild;break;}}}}/****************************************二叉排序树的操作结束**********************************************//*****************************************哈希表的操作开始********************************************/typedef int KeyType; //设关键字域为整形,需要修改类型时,只需修改这里就可以  const int NULLKEY=0; //NULLKEY表示该位置无值  int hashsize[]={11,19,29,37,47}; //hash表容量递增表  int hash_length=0;//hash表表长 typedef struct  {   //数据元素类型 int key;  int ord;   }Elemtype;  typedef struct {Elemtype *elem; //数据元素数组,动态申请  int count;// 当前数据元素个数  int size; //决定hash表的容量为第几个,hashsize[size]为当前hash容量  }HashTable;HashTable * initHashTable(){HashTable *table =(HashTable *) malloc(sizeof(HashTable));int i = 0;table->count = 0;hash_length = table->size = hashsize[0];table->elem = (Elemtype *)malloc(sizeof(Elemtype)*hash_length);for(i=0;i<hash_length;i++){table->elem[i].key=NULLKEY;  }return table;}void destroy_HashTable(HashTable *&table){  free(table->elem);table->elem=NULL;  table->count=0;  table->size=0;  }  int Hash(int k){   //hash函数的一种(取模法)  return k%hash_length;  }  int Collision(int p,int d){  //解决冲突   p = (p+d)%hash_length; //采用开放地址法里的线性探测   return p;}  int Search_Hash(HashTable *&table,int k){  //查找 //在开放地址hash表中查找关键字等于k的元素  //若找到用p表示待查数据,查找不成功时,p指向的是可插入地址  int c = 0,p = -1;p=Hash(k); //求hash地址  while(table->elem[p].key!=NULLKEY && table->elem[p].key!=k) {  c++;  if(c<hash_length){p = Collision(p,c); } else {break;}}  if (c>=hash_length){return -1;}return p;}  int Insert_Hash(HashTable *&table,Elemtype e)  {  //插入 //在查找不成功的情况下将k插入到hash表中  int p,c = 0;  //printf("the key is %d and the pos is %d\n",e.key,Search_Hash(table,e.key));if(Search_Hash(table,e.key) == -1){return -1; //表示该元素已在hash表中  }else {p=Hash(e.key); //求hash地址while(table->elem[p].key!=NULLKEY) {   c++;if(c<hash_length){p = Collision(p,c); } else {p = -1;break;}}  //printData(p);if (p != -1){//插入e  table->elem[p]=e;  (table->count)++; return 1;  } else {return -1;} }  }  void Traverse_HashTable(HashTable *& hashTable){int i = 0;for(i = 0;i<hash_length;i++){if ((hashTable->elem[i].key) != NULLKEY){printData2(hashTable->elem[i].key);}}}void hashTableOperation(){HashTable * table = initHashTable();int i = 0;Elemtype type;for (i = 0;i<10;i++){type.key = nums1[i];Insert_Hash(table,type);}Traverse_HashTable(table);}/*****************************************哈希表的操作结束********************************************///判断一个二叉树是不是平衡二叉树int judgeIsAVLOrNot(BiNode * root){if (root== NULL){return 1;} else if (root->lchild == NULL && root->rchild == NULL){return 1;}else if ((root->lchild != NULL && root->lchild->rchild != NULL && root->rchild == NULL) ||(root->lchild != NULL && root->lchild->lchild != NULL && root->rchild == NULL) ||(root->rchild != NULL && root->rchild->rchild != NULL && root->lchild == NULL)||(root->rchild != NULL && root->rchild->lchild != NULL && root->lchild == NULL)){return 0;} else {return judgeIsAVLOrNot(root->rchild)*judgeIsAVLOrNot(root->lchild);}}//逆序输出二叉排序树void destOrderTraverse(BiNode * root){if (root == NULL){return ;} destOrderTraverse(root->rchild);printData2(root->data);destOrderTraverse(root->lchild);}//简单哈希表,哈希函数为余数法,冲突处理方法为开放地址法;void smipleHash(){typedef struct HashTable{int *num;int count;int len ;}HashTable;//初始化int i = 0;HashTable table ;table.count = 0;table.len = 13;table.num = (int*)malloc(sizeof(int)*13);for (i = 0;i<table.len;i++){table.num[i] = -1;}int step;for (i = 0;i<10;i++){step = 1;if (table.num[nums3[i]%table.len] == -1){table.num[nums3[i]%table.len] = nums3[i];table.count++;} else {while(table.num[(nums3[i]+step)%table.len] != -1){step++;}table.num[(nums3[i]+step)%table.len] = nums3[i];table.count++;}}for (i = 0;i<table.len;i++){printData2(table.num[i]);}}void main(){printInfo("递归折半查找:\n");printData(binSearch(0,9,10));printInfo("\n\n");binSearch2(10);printInfo("\n\n");BiNode* root =  createBST();printInfo("前序:\n");preOrderTraverse(root);printInfo("\n");printInfo("中序:\n");inOrderTraverse(root);printInfo("\n");printInfo("后序:\n");postOrderTraverse(root);printInfo("\n\n");printInfo("二叉排序树的查找:");searchBST(root,1);printInfo("\n\n");printInfo("二叉排序树的删除:");deleteBST(&root,7);inOrderTraverse(root);printInfo("\n\n");printInfo("二叉排序树的插入:");insertBST(&root,7);inOrderTraverse(root);printInfo("\n\n");printInfo("哈希表的建立和输出:\n");hashTableOperation();printInfo("\n\n");printInfo("二叉排序树倒叙输出:\n");destOrderTraverse(root);printInfo("\n\n");smipleHash();printInfo("\n\n");printInfo("判断一个二叉树是不是平衡二叉树:\n");BiNode* root2 =  createBST();if (judgeIsAVLOrNot(root2) == 1){printInfo("平衡");} else {printInfo("不平衡");}printInfo("\n\n");}


原创粉丝点击