• 【数据结构】查找算法和堆栈的应用


    查找算法

    (1)查找算法分别是顺序查找 mid查找(折半,插入,斐波那契)

    前者的操作复杂度都是n,后面三个的操作复杂度是log2n

    (2)关于后面三种东西的具体实现

    1. //顺序查找是n,剩下三种最坏的时候都是log2n
    2. //此外,剩下的三种都要求程序已经按顺序排好,区别就在于mid的选取不同
    3. int searchTwo(int *arr,int start,int end,int num){
    4. if(start>=end){
    5. return -1;
    6. }else{
    7. int mid=(start+end)/2;//另外三种查找方法,区别其实就在于如何获取mid的数值
    8. if(num==arr[mid]){
    9. return mid;
    10. }else if(num<arr[mid]){
    11. return searchTwo(arr,start,mid-1,num);
    12. }else if(num>arr[mid]){
    13. return searchTwo(arr,mid+1,end,num);
    14. }
    15. }
    16. }

    (折半的函数为)

    start+end/2
    

    (插差值寻找的函数是)‘

    利用了一个概率分布的性质进行寻找的

    start+(num-arr[start])*(end-start)/(arr[end]-arr[start]))

    斐波那契的查找函数)

    斐波那契数的一个性质就是,n越大,(n-1)/n更接近黄金比例0.618.。。。。’

    说白了斐波那契还是没事找事。。。。。

    例如斐波那契相邻两项是  8  13,又加入现在的范围是(0,12),长度刚好为十三,那么就可以划分为一个长度为8和长度为5的两个部分,mid就是8+0-1=7

    不过这个递归方法和上面的不一致,之前的查找都是找到一个分界点,然后分界点前后划分开

    (start,mid-1)和(mid+1,end) 

    而这个递归方法,为了保证斐波那契数列长度的完整性,需要的递归区间是

    (start,mid)和(mid+1,end) 

    1. int F(int k){
    2. if(k==1){return 1;}
    3. else if(k==0){return 0;}
    4. else{return F(k-1)+F(k-2);}
    5. }
    6. int fbnq_mid(int start,int end){//这里保证传进来的数字足够组成斐波那契数列
    7. int k=0; //具体对应实际情况的时候,可能要对数组进行补全操作才行
    8. int length=end-start+1; //数组有效长度n到最近的一个斐波那契数字之间,全部填充
    9. while(length!=F(k)){ //其实本质上,只是在利用0.618的例子。。。。没啥劲
    10. k++;
    11. }
    12. return F(k-1);
    13. }

    堆栈的应用

    1.n皇后问题实际上是一种递归回溯问题,其实和树/图结构里面dfs的本质很接近,如果画出图来就可以看出是另一种形式树的延申(离散中的树结构穷举)

    2.n皇后的规则:

    在一个n*n的矩阵中,每个皇后同行同列,以及对角线位置上不能有其他皇后,写出所有符合条件的皇后排列情况(这里以8皇后的情况为例子)

    3.实现思路:

    (1)数组的序号代表列,数组arr[x]=y代表第x列的皇后在第y行

    (2)递归的时候以列作为参数,每到一个列的时候,遍历0-7每一行,如果有一个位置可行,就沿着这个情况继续递归,当递归结束返回这里的时候,在这一列继续往下找可行的点;

    (3)递归结束的条件为当前找到的点就是最后一列,就输出这个图

    4.代码实现如下

    1. //n皇后问题
    2. //n皇后问题的原理很简单貌似,其实就是
    3. //这里举个例子,8皇后问题
    4. int arr[8];
    5. void graph() {
    6. for (int i = 0; i <= 7; i++) {
    7. for (int j = 0; j <= 7; j++) {
    8. if (arr[j] == i) {
    9. cout << "";
    10. }
    11. else {
    12. cout << "<->";
    13. }
    14. }
    15. cout << endl;
    16. }
    17. }
    18. //攻击问题的验证方法:
    19. //如果和之前列的某个皇后行数相同
    20. //或者在对角线上(行列差的绝对值相等就是在对角线上)
    21. bool attack(int x,int y) {//x为列数,y为行数
    22. for (int i = 0; i < x; i++) {
    23. int offx = abs(i-x);
    24. int offy = abs(arr[i] - y);
    25. if (offx == offy || offy == 0) {
    26. return true;
    27. }
    28. }
    29. return false;
    30. }
    31. //n皇后问题的回溯原理:
    32. //每一列的每一行都尝试一次,如果整个点不被攻击,就往下一行递归
    33. //如果已经是第七列了,则每确定一个点,就可以打印一次
    34. void nQueen(int x) {
    35. for (int i = 0; i <= 7; i++) {
    36. if (!attack(x,i)) {
    37. arr[x] = i;
    38. if (x == 7) {
    39. graph();
    40. system("pause");
    41. }
    42. else {
    43. nQueen(x + 1);
    44. }
    45. }
    46. }
    47. }

  • 相关阅读:
    基于YOLOV8+移动窗口切片(完整版)+OnnxRuntime+KMeans+Zbar+传统图像处理算法的大图片小目标光伏产线条码检测研究
    免费开源的在线手绘画图工具
    vue之数据驱动
    Python爬虫(二十二)_selenium案例:模拟登陆豆瓣
    数据结构(c语言版) 队列
    OpenHarmony网络协议通信—libevent [GN编译] - 事件通知库
    PicGo配置阿里云oss
    AWS使用 Client VPN 配置访问VPC 内网资源
    [线程与网络] 网络编程与通信原理(四):深入理解传输层UDP与TCP协议
    【博客444】Linux Macvlan
  • 原文地址:https://blog.csdn.net/weixin_62697030/article/details/127879521