• 数据结构学习笔记(第七章 查找)


    目录

    基本概念

    静态查找:

    动态查找:

    线性结构

    顺序查找

    折半查找

    分块查找

    树形结构

    二叉排序树

    平衡二叉树

    红黑树

    B树

    散列表

    散列函数的构造方法

    处理冲突的方法 


    基本概念

    静态查找:

    在静态查找表上进行的查找操作,查找满足条件的数据元素的储存位置或者各种属性。

    静态查找有三种查找方式:顺序查找、折半查找和散列查找。

    动态查找:

    需动态的插入或删除的查找表。

    查找方式有:二叉排序树查找和散列查找,二叉排序树和B树都是二叉排序树的改进。

    线性结构

    顺序查找

    顺序查找又称线性查找,顾名思义,就是按顺序依次查找元素。对顺序表和链表都适用。

    1. typedef int ElemType;
    2. typedef struct{
    3. ElemType *elem;//整形指针
    4. int TableLen; //存储动态数组元素个数
    5. }SSTable;
    6. int Search_Seq(SSTable ST,ElemType key){
    7. ST.elem[0]=key;//作为哨兵
    8. int i;
    9. for(i=ST.TableLen-1;ST.elem[i]!=key;--i);
    10. return i;
    11. }

    折半查找

    又称二分查找,仅适用于有序顺序表。顾名思义,每次查找都拿中间元素比较。

    1. int Binary_Search(SSTable L,ElemType key){
    2. int low=0,high=L.TableLen-1,mid;
    3. while(low<=high){
    4. mid=(low+high)/2;
    5. if(L.elem[mid]==key){
    6. return mid;
    7. }
    8. else if(L.elem[mid]>key){
    9. high=mid-1;
    10. }else{
    11. low=mid+1;
    12. }
    13. }
    14. return -1;
    15. }

    分块查找

    又称索引顺序查找,吸收了顺序查找和折半查找的优点,既有动态结构,又适用于快速查找。

    主要思想:将查找表分为若干块,块内元素可以无序,但块之间是有序的,即第一块最大的关键字(元素)小于第二个块中所有关键字。在建立一个索引表,索引表中包括各块最大关键字和各块第一个元素地址,索引表按关键字有序排列。

    查找过程:第一步查找所在块,可以顺序或折半查找索引表。第二步在块内顺序查找。

    树形结构

    二叉排序树

    又称二叉查找树,核心思想:左子树值<根节点值<右子树值,所以对其进行中序遍历,可以得到递增有序序列。1 2 3 4 6 8

    1. //结构定义
    2. typedef int KeyType;
    3. typedef struct BSTNode{
    4. KeyType key;
    5. struct BSTNode *lchild,*rchild;
    6. }BSTNode,*BiTree;
    7. //插入
    8. int BST_Insert(BiTree &T,KeyType k){
    9. if(T==NULL){
    10. T=(BiTree)malloc(sizeof(BSTNode));
    11. T->key=k;
    12. T->lchild=T->rchild=NULL;
    13. return 1;//插入成功
    14. }
    15. else if(k==T->key){
    16. return 0;//发现相同元素,不插入
    17. }
    18. else if(kkey){
    19. return BST_Insert(T->lchild,k);
    20. }
    21. else{
    22. return BST_Insert(T->rchild,k);
    23. }
    24. }
    25. //建表
    26. void Create_BST(BiTree &T,KeyType str[],int n){
    27. T=NULL;
    28. int i=0;
    29. while(i
    30. BST_Insert(T,str[i]);
    31. i++;
    32. }
    33. }
    34. //中序
    35. void InOrder(BiTree T){
    36. if(T!=NULL){
    37. InOrder(T->lchild);
    38. printf("%3d",T->key);
    39. InOrder(T->rchild);
    40. }
    41. }
    42. //查找
    43. BSTNode *BST_Search(BiTree T,KeyType key,BiTree &p){
    44. p=NULL;
    45. while(T!=NULL&&key!=T->key){
    46. p=T;
    47. if(keykey)
    48. T=T->lchild;//比当前结点小,往左找
    49. else
    50. T=T->rchild;//反之往右
    51. }
    52. return T;
    53. }
    54. //删除
    55. void DeleteNode(BiTree &root,KeyType x){
    56. if(root==NULL){
    57. return;
    58. }
    59. if(root->key>x){
    60. DeleteNode(root->lchild,x);
    61. }else if(root->key
    62. DeleteNode(root->rchild,x);
    63. }else{//找到了
    64. if(root->lchild==NULL){//左子树为空
    65. BiTree tempNode=root;
    66. root=root->rchild;
    67. free(tempNode);
    68. }else if(root->rchild==NULL){//右子树为空
    69. BiTree tempNode=root;
    70. root=root->lchild;
    71. free(tempNode);
    72. }else{//左右子树非空
    73. BiTree tempNode=root->lchild;
    74. if(tempNode->rchild!=NULL){
    75. tempNode=tempNode->rchild;
    76. }
    77. root->key=tempNode->key;
    78. DeleteNode(root->lchild,tempNode->key);
    79. }
    80. }
    81. }

    平衡二叉树

    简称平衡树。特点:左右子树高度差绝对值不超过1。因此平衡因子可能为-1,0,1。

    平衡二叉树详解 通俗易懂_邓嘉文Jarvan的博客-CSDN博客_平衡二叉树

    红黑树

    漫画:什么是红黑树?(整合版)_程序员小灰的博客-CSDN博客

    B树

    又称多路平衡查找树

    B树和B+树_ZJE_ANDY的博客-CSDN博客_b树的阶数

    什么是B-树?(详细图解)_初念初恋的博客-CSDN博客_b-树

    B-树的详解_Ouyang_Lianjun的博客-CSDN博客_b-树

    散列表

    散列函数:一个把查找表中的关键字映射成该关键字对应的地址函数,记为Hash(key)=Addr,这里地址可以是数组下标,索引或内存地址。

    冲突:把两种或两种以上不同关键字映射到同一地址。

    同义词:发生碰撞的不同关键字。

    散列表:根据关键字而直接访问的数据结构。(散列表建立了关键字和存储地址之间的直接映射关系)

    散列函数的构造方法

    1.直接定址法

    H(key)=key或H(key)=a*key+b,a和b为常数

    2.除数留余法

    H(key)=key%p,p为不大于表长但最接近表长的质数

    3.数字分析法

    4.平方取中法

    处理冲突的方法 

    1.开放定址法

     其中增量取法有四种,分别为线性探测法,平方探测法,双散列法和伪随机序列法。

    详细增量取法请看下面的链接,写的比较详细。

    散列表(开放定址法)_时代&信念的博客-CSDN博客_开放定址法

    2.拉链法

     下面是一个示例代码,仅供参考。

    1. int hash(const char* key)
    2. {
    3. int h = 0, g;
    4. while (*key)
    5. {
    6. h = (h << 4) + *key++;
    7. g = h & 0xf0000000;
    8. if (g)
    9. {
    10. h ^= g >> 24;
    11. }
    12. h &= ~g;
    13. }
    14. return h % MaxKey;//算出下标要取余
    15. }
    16. int main()
    17. {
    18. const char* pStr[5] = { "xiongda","lele","hanmeimei","wangdao","fenghua" };
    19. int i;
    20. const char* pHash_table[MaxKey] = {NULL};//哈希表,散列表
    21. for (i = 0; i < 5; i++)
    22. {
    23. printf("%s is key=%d\n", pStr[i], hash(pStr[i]));//算哈希值并打印
    24. pHash_table[hash(pStr[i])] = pStr[i];//存入哈希表
    25. }
    26. return 0;
    27. }
  • 相关阅读:
    微信小程序——使用插槽slot快捷开发
    时间序列预测:用电量预测 05 BP神经网络
    vue2知识点————(父子通信)
    C++多态(超级详细版)
    SpringBoot视图渲染技术
    断网重连里面的长连接,短链接和心跳机制
    Android随笔-ClassLoader
    字节跳动端智能工程链路 Pitaya 的架构设计
    SICP:惰性求值、流和尾递归(Python实现)
    【cpolar】Ubuntu本地快速搭建web小游戏网站,公网用户远程访问
  • 原文地址:https://blog.csdn.net/weixin_53011574/article/details/125894859