加载中...

数据结构

数据结构

数据结构的研究

数据结构的基本概念

数据

是能输入计算机并且能被计算机处理的各种符号的集合

数据项

构成数据元素的最小的单位

数据元素(是数据的集合的个体)

数据对象(是数据的集合的子集)

数据结构概念

带有结构的数据元素的集合

算法和算法分析

算法

解决问题的一种办法

算法特性

算法的设计要求

数据的存储结构

线性表

线性起点

线性表的起点

终端结点

线性表的终点

其余名词

单个元素中 前面的叫前趋,后面的叫后继(第一个,最后一个无)

顺序存储【数组】

                                    优点

                                                            存储速度快

                                    缺点

                                                            实现需要知道长度

                                                            操作的空间复杂度很高

                                                            空间通常是有限制的

                                                            需要大块连续的内存块

数组代码的演示

C 语言语法
#include<stdio.h>
 #include<stdlib.h>
 #include<malloc.h>
 
 struct arr{
     int * pBase;
     int cnt;
     int len;
 };
 void arr_init(struct arr * pArr,int lenght);
 bool is_empty(struct arr * pArr);
 bool is_full(struct arr * pArr);
 void arr_inversion(struct arr * pArr);
 bool arr_append(struct arr * pArr,int value);
 bool arr_insert(struct arr * pArr,int pos,int value);
 bool arr_delete(struct arr * pArr,int pos,int * val);
 void arr_show(struct arr * pArr);
 
 int main(){
     struct arr Arr;
     // int val;
     arr_init(&Arr,6);
     arr_append(&Arr,1);
     arr_append(&Arr,2);
     arr_append(&Arr,3);
     arr_append(&Arr,4);
     arr_append(&Arr,5);
     arr_append(&Arr,6);
     arr_append(&Arr,7);
     //arr_show(&Arr);
     
     /*
     if(arr_delete(&Arr,2,&val)){
         printf("删除成功,你删除的元素是%d",val);
     }
     else
         printf("删除失败");*/
 
     return 0;
 }
 void arr_init(struct arr * pArr,int lenght){
     pArr->pBase=(int *)malloc(sizeof(int)*lenght);
     if(pArr->pBase==NULL){
     printf("内存分配失败"); 
         exit(-1);
     }
     else {
         printf("内存分配成功,首字节地址为%p\n",pArr->pBase); 
                 pArr->cnt=0;
                 pArr->len=lenght;
     }
                 
 }
 bool is_empty(struct arr * pArr){
     if(pArr->cnt==0){
         return true;
     }
     else 
         return false;
 }
 bool is_full(struct arr * pArr){
     if(pArr->cnt==pArr->len){
         return true;
     }
     else 
         return false;
 }
 void arr_inversion(struct arr * pArr){
     int i = 0;
     int j = pArr->cnt-1;
     int t;
     while(i<j){
         t = pArr->pBase[i];
         pArr->pBase[i]=pArr->pBase[j];
         pArr->pBase[j]=t;
         i++;
         j--;    }   
 }
 bool arr_append(struct arr * pArr,int value){
     if(is_full(pArr))
     {
         printf("warning");
         return false;
     }
         
     pArr->pBase[pArr->cnt]=value;
     (pArr->cnt)++;
     return true;
 }
 bool arr_insert(struct arr * pArr,int pos,int value){
     if(is_full(pArr))
         {
             printf("warning");
             return false;
         }
     if( pos<1 || pos>pArr->cnt)
             return false;
 
     for(int i=pArr->cnt-1;i>=pos-1;i--){
         pArr->pBase[i+1]=pArr->pBase[i];
     } 
         pArr->pBase[pos-1]=value;
         (pArr->cnt)++;
     return true;
 }
 
 bool arr_delete(struct arr * pArr,int pos,int * val){
     if(is_empty(pArr)){
         return false;
     }
     _val = pArr->pBase[pos-1];
     for(int i=pos;i<=pArr->cnt-1;i++){
     pArr->pBase[i-1]=pArr->pBase[i];
     } 
         (pArr->cnt)--;
     return true;
 }
__ void arr_show(struct arr _ pArr){
     if(is_empty(pArr)){
         printf("arr is empty");
     }
     for(int i=0;i<pArr->cnt;i++){
         printf("%d ",pArr->pBase[i]);
     }
 }
C++ 标准化写法
//2023年10月17日 22点33分  first write by wbc 
#include <stdio.h>
#include <iostream>       //io输出流 
#include <stdlib.h>
using namespace std;          //声明std空间 

#define OK 1          //理论bool直接返回可忽略 
#define ERROR 0
#define MAX 100       //最大长度100 可手动函数输入 
#define OVERFLOW -2       //配合exit溢出 

typedef int Status;       //函数返回状态条件 
typedef int ElemType;         //定义本次操作元素 

typedef struct {
    ElemType * elem;
    int len;         //当前长度 最好书写cnt作于与MAX长度区分 
}SqList;

//下列const只为了锁定函数的操作性 提高安全 
//整体使用引入类型并非指针 
Status initList(SqList& l);       //初始化空间返回状态值      
Status destoryList(SqList& l);        //释放空间返回状态值 
bool isEmpty(SqList& l);          //判断是否为空 
bool isFull(SqList& l);       //判断列表是否已满 
int getLen(SqList& l);        //获得长度 
void clearList(SqList& l);        //伪清理 实际无用 
bool getElem(SqList& l, int pos, ElemType& e);        //获得元素 
int locateElem(SqList& l, ElemType e);        //查找元素位置 
Status insertElem(SqList& l, int pos, ElemType val);          //插入元素 
Status deleteElem(SqList& l, int pos);        ///删除元素 
bool appendElem(SqList& l, ElemType val);         //追加元素 
void inversionList(SqList& l);        //倒置链表 
void printfList(SqList& l);       //打印列表 





Status initList(SqList& l){
    l.elem = new ElemType[MAX];
    /*
    可以使用库函数调用malloc.h C写法 
    l.elem = (ElemType *)malloc((sizeof(ElemType)*MAX));
    */
    if (l.elem == NULL)
       exit(OVERFLOW);
    else{
       l.len = 0;
       cout << "is ok" <<endl; //等同printf 
       return OK;
    }
}

Status destoryList(SqList& l){
    if (l.elem != NULL){
       delete[] l.elem;
       //可用 free(l.elem) C写法 
       l.elem = NULL;
       l.len = 0; 
       cout << "destory the space"<<endl;
    }
    
    return OK;
}

bool isEmpty(SqList& l){
    if(l.len == 0)
       return true;
    else 
       return false;
}

bool isFull(SqList& l){
    if(l.len == MAX){
       return true;
    }
    else{
       return false;
    }
}

int getLen(SqList& l){
    return l.len;
}

void clearList(SqList& l){
    l.len = 0;
}

bool getElem(SqList& l, int pos, ElemType& e){
    //通过位置 操纵回返回到 e变量中 
    if(pos < 1 || pos > l.len){
       return false;
    }
    e = l.elem[pos-1];
    return true;
}

int locateElem(SqList& l, ElemType e){
    //通过元素 查找位置 
    for(int i=0;i<l.len;i++){
       if(e == l.elem[i]){
          return i+1;
       }
    } 
    return ERROR;
}

Status insertElem(SqList& l, int pos, ElemType val){
    //插入范围 1--当前表长度+1 
    if(pos < 1 || pos > l.len + 1){
       return ERROR;
    } 
    if(isFull(l)){
       return ERROR;
    }
    
    for(int j = pos - 1 ;j <= l.len -1 ;j--){
       l.elem[j+1] = l.elem[j]; 
    }
    
    l.elem[pos-1] = val;
    l.len ++;
    
    return OK;
}

Status deleteElem(SqList& l, int pos){
    //删除范围1 -- 当前长度 
    if(pos  < 1 || pos > l.len){
       return ERROR;
    }
    if(isEmpty(l)){
       return ERROR;   
    } 
    
    for(int j = pos ;j < l.len; j++){
       l.elem[j-1] = l.elem[j];
    } 
    l.len--;
    
    return OK;
}

bool appendElem(SqList& l,ElemType val){
    if(isFull(l)){
       return false;
    }
    
    l.elem[l.len] = val;
    l.len++;
    return true;
} 

void inversionList(SqList& l){
    Status i = 0;
    Status j = l.len-1;
    Status t;
    while(i<j){
       t = l.elem[i];
       l.elem[i] = l.elem[j];
       l.elem[j] = t;
       i++;
       j--; 
    }
}

void printfList(SqList& l){
    for(int i=0;i<l.len;i++){
    cout << l.elem[i] <<endl;
    // printf("%d",l.elem[i]);
       
    } 
}


int main(){
    SqList l;
    initList(l);
    insertElem(l,1,3);

    appendElem(l,1);

   
       appendElem(l,2);
          appendElem(l,3);
             appendElem(l,4);
             
    printfList(l);
    destoryList(l);
     
    
}

链式存储结构【数组】

                                    优点

                                                            空间没有限制

                                                            插入删除元素很快

                                    缺点

                                                            存储速度很慢

图列说明

术语

结点:数据元素的存储映像 n 个结点组成链表

链表分类

单链表(线性链表)

双链表(一个节点两个指针域)

循环链表

首尾相接为循环链表

链表代码演示

#include<stdio.h>
 #include<malloc.h>
 #include<stdlib.h>
 
 typedef struct Node{
     int data; //数据域
     struct Node * pNext;//地址域
 }NODE, _PNODE;
 
 PNODE list_create();
 void list_show(PNODE pHead);
 bool is_empty(PNODE pHead);
 void  list_sort(PNODE pHead);
 int list_len(PNODE pHead);
 void list_append(PNODE pHead,int pos,int val);
__ bool list_delete(PNODE pHead,int pos,int _ pVal);
  
 
 
  
  
 int main(){
     PNODE  pHead = NULL;
     pHead = list_create();
     list_sort(pHead);
     list_show(pHead);
     return 0;
 }
 
 
 PNODE list_create(){
     PNODE pHead = (PNODE)malloc(sizeof(NODE)) ;
     if(pHead == NULL){
         exit(-1);
     }
     int i, len, val;
     printf("len is ?");
     scanf("%d",&len);
     
     PNODE pTail = pHead; //定义尾指针实现一直擦插入
     pTail->pNext = NULL; //保证0个数据头指针清空
  
     for(i=0;i<len;i++){
         printf("please write %d data",i+1);
         scanf("%d",&val);
     
         PNODE pNew = (PNODE)malloc(sizeof(NODE)) ;
             if(pNew == NULL){
                 exit(-1);
             }
         pNew->data = val; //保存数据
         pTail->pNext=pNew; //插入
         pNew->pNext = NULL; //初始化指针域
         pTail=pNew; //切换尾指针
     }
         return pHead;
 } 
 
 void list_show(PNODE pHead){
     PNODE  p = pHead->pNext;
     while(p->data != NULL){
         printf("%d ",p->data);
         p = p->pNext;
     }    
 }
 
 bool is_empty(PNODE pHead){
     PNODE p = pHead->pNext;
     if(p == NULL){
         return true;
     }
     return false;   
 }
 
 int list_len(PNODE pHead){
     int i=0;
     PNODE p = pHead->pNext; //读第一个数据
     
     while(p!=NULL){
         i++;
         p = p->pNext;
     }
     
     return i;
 }
 
 void list_sort(PNODE pHead){
     int i, j, t;
     int len=list_len(pHead);
     PNODE p,q; //选择算法
     for(i=0,p=pHead->pNext;i<len-1;i++,p=p->pNext){
         for(j=i+1,q=p->pNext;j<len;j++,q=q->pNext){
             if(p->data > q->data){ //排序从小到大
                 t = p->data;
                 p->data = q->data;
                 q->data = t;    //TODO
             }   
         }   }
 }
 
 void list_append(PNODE pHead,int pos,int val){
     int i = 0;
     PNODE p = pHead;
 
     while(p!=NULL && i<pos-1){
         i++;
         p = p->pNext;
     }
     
     if(p ==NULL || i>pos-1){
     exit(-1);
     }
     //指向插入前一个数据的位置且判断是否为空
     
     PNODE pNew = (PNODE)malloc(sizeof(NODE)); //新内存创建
     if (NULL == pNew)
     {
         printf("动态分配内存失败!\n");
         exit(-1);
     }
     pNew->data = val; 
     
     PNODE q = p->pNext; //存储旧位置
     p->pNext = pNew;//新数据连接
     pNew->pNext = q;//旧位置链接
 }
 bool list_delete(PNODE pHead,int pos,int * pVal){
     int i = 0;
     PNODE p = pHead;
     
     while(p->pNext!=NULL && i<pos-1){
         p = p->pNext;
         ++i;
     }
     if(p->pNext == NULL || i>pos-1){
         exit(-1);
     }
     //指针偏移到删除数据的前一个位置且判断删除数据是否空
     
     *pVal = p->data;  //保存数据
     PNODE q = p->pNext; //指向删除位置
     
     p->pNext = p->pNext->pNext; //断链
     free(q); //释放删除空间
     q = NULL; //初始化指针地址
     
     return true;
  
 }
//C++
#include <stdio.h>
#include <iostream>
using namespace std;

#define OVERFLOW -2
#define OK 1
#define ERROR 0

typedef int status;
typedef int elemType;

typedef struct Node{
        elemType data;
        struct Node * pNext;
}NODE, *PNODE;

//使用引用类型无需初始化L指针

//分配头指针空间 清空头指针地址存储 
status initList(PNODE& L){
        L = new NODE;
        if(L == NULL){
                exit(OVERFLOW);
        }
        L->pNext = NULL;
        cout <<"pHead is ok "<<endl;
        return OK;
        
}

//利用P 摧毁头指针 
void destoryList(PNODE& L){
        PNODE P;
         while(L){
                P = L;
                L = L->pNext;
                delete P;
        }
         L = NULL;        
}

//计算包括头节点长度 
int getLen(PNODE& L){
        PNODE P;
        P = L->pNext; 
        int cnt = 0;
        while(P){
                cnt++;
                P = P->pNext;
        }
        
        return cnt;
} 


//摧毁头指针以外一切 
void clearList(PNODE& L){
        PNODE P = L->pNext;
        L->pNext = NULL;
        destoryList(P);
}

//寻找元素地址 
PNODE locateAddess(PNODE& L,elemType e){
        PNODE P = L->pNext;
        while(P != NULL && P->data != e){
                P = P->pNext;
        }
        
        return P;
}

//验证链表是否为空 
bool isEmpty(PNODE& L){
        PNODE P = L->pNext;
        if(P == NULL){
                return false;
        }
                return        true;
        
        
} 


status getEleme(PNODE& L, int pos, elemType& e){
        int i = 0;
        PNODE P = L;
        while(P != NULL  && i<pos){
                i++;
                P = P->pNext;
        }
        //防止pos异常 
        if(P == NULL || i > pos){
                exit(OVERFLOW);
        }
        e  = P->data;
        return OK;
}

status insertList(PNODE& L, int pos, int val){
        int i = 0;
        PNODE P = L;
        while(P != NULL && i < pos - 1){
                i++;
                P = P->pNext;
        }
        
        if(P == NULL || i > pos -1){
                exit(OVERFLOW);
        }
        
        PNODE Pnew = new NODE;
        if(Pnew == NULL){
                exit(OVERFLOW);
        } 
        
        //新空间给值 
        Pnew->data = val;
        
        //指针指向操作循环出的下一个空间
        // 给 新空间地址 
        PNODE Q = P->pNext;
        P->pNext = Pnew;
        Pnew->pNext = Q;
        
        return OK;
} 

status deleteList(PNODE& L, int pos,elemType& e){
        int i = 0;
        PNODE P = L; 
        
        while(P  != NULL && i < pos-1){
                i++;
                P = P->pNext;
        }
        
        if(P->pNext == NULL || i > pos-1){
                exit(OVERFLOW);
        }
        
        PNODE Q = P->pNext;
        e = Q->data;
        P->pNext = Q->pNext;        
        delete Q;
        
        return OK;
}

void printList(PNODE& L){
        PNODE P = L->pNext;
        
        while(P->data){
                cout << P->data <<endl;
                P = P->pNext;
        }
}


 void createRear(PNODE& L, int len){
        
        elemType val;
        cout <<"len is ?"<<endl;
        cin >> len;
        
        PNODE pTail = L;
        if(pTail == NULL){
                exit(OVERFLOW);
        } 
        
        
        for(int i=0;i<len;i++){
                printf("你输入的第%d个元素是  ",i+1);
                
                scanf("%d",&val);
                
                PNODE pNew =  new NODE;
                if(!pNew){
                        exit(OVERFLOW);
                }
                pNew->data = val;
                pTail->pNext = pNew;
                pNew ->pNext = NULL;
                pTail = pNew;
                
                
        }
        
}

        
void createHead(PNODE& L,int n){
        for(int i=0;i<n;i++){
                PNODE pNew = new NODE;
                cin >> pNew->data;
                pNew->pNext = L->pNext;
                L->pNext = pNew;
        }
} 
        
//选择排序法 
void sortList(PNODE& L){
        int i, j;
        elemType t;
        int len = getLen(L);
        PNODE P, Q;
        for(i = 0,P = L->pNext;i<len-1;i++,P=P->pNext){
                for(j = i+1,Q = P->pNext;j< len;j++,Q = Q->pNext){
                        t = P->data;
                        P->data = Q ->data;
                        Q->data = t; 
                }
        }
}



int main(){
        PNODE p  = new NODE;
        if(p == NULL){
                cout << 1;
                        
        }  
}

线性结构的应用--栈

定义

一种可以实现”先进后出“的存储结构

分类

静态栈:

是用数组来实现

工作原理

pBottom:指向头节点(里面并不存放有效数据),栈底元素的下一个
pTop :指向尾结点
删除元素:pTop 向上移动
插入元素:pTop 向下移动

动态栈代码应用演示

# include <stdio.h>
 # include <malloc.h>
 # include <stdlib.h>
 
 typedef struct Node
 {
     int data;
     struct Node * pNext;
 }NODE, * PNODE;
 
 typedef struct Stack
 {
     PNODE pTop;
     PNODE pBottom;
 }STACK, * PSTACK;  //PSTACK ????? struct STACK *
 
 void init(PSTACK);
 void push(PSTACK, int );
 void traverse(PSTACK);
 bool pop(PSTACK, int _);
 void clear(PSTACK pS);
 bool empty(PSTACK pS);
 
 int main(void){
     STACK S;
     init(&S);
     push(&S,6);
     push(&S,67);
 
     
     clear(&S);
     traverse(&S);
     
 
     
     return 0;
 }
 
 void init(PSTACK pS){
     pS->pTop = (PNODE)malloc(sizeof(PNODE));//分配指向空间 
     if(pS->pTop == NULL){
         printf("warning"); 
     }
     else{
         pS->pBottom = pS->pTop;//给予低指针指向 
         pS->pTop->pNext = NULL;//清空指针域 
     }
 }
 
 void push(PSTACK pS, int val){
     PNODE pNew = (PNODE)malloc(sizeof(PNODE));
     pNew->data = val;
     pNew->pNext = pS->pTop;//链接 
     pS->pTop = pNew;//改变顶指针 
 }
 
 void traverse(PSTACK pS){
     PNODE p = pS->pTop;
 
     while(p != pS->pBottom){
         printf("%d ",p->data);
         p = p->pNext;
     }
     
     return;
     
 }
 
 bool empty(PSTACK pS){
     if(pS->pBottom == pS->pTop){
         return true;
     }
     else
         return false;
 } 
 
__ bool pop(PSTACK pS, int _ pVal){
     if(empty(pS)){
         return true;
     }
     else
     {
         PNODE r = pS->pTop; //新建指针指向释放空间 
         * pVal = r->data;
         pS->pTop = r->pNext;//改变顶指针指向 
         //释放空间 初始化指针 
         free(r);
         r = NULL;
         
     }
     return true;
     
 }
 
 void clear(PSTACK pS){
     PNODE  p = pS->pTop;//双指针交替 
     PNODE  q = NULL;
     while(p != pS->pBottom){
           q = p->pNext;
           free(p);
           p = q; 
       }
       pS->pTop = pS->pBottom;//恢复pTop指向 防止内存外溢 
 }

线性结构的应用--队列

对递归的理解

定义:一个函数,直接或者间接,调用自己。

函数调用思想

当在一个函数的运行期间调用另一个函数时,在运行被调函数之前,系统需要完成三件事:

从被调函数返回函数之前,系统也要完成三件事:

递归需要满足的条件

汉诺塔

汉诺塔伪算法思路

汉诺塔整体代码

#include<stdio.h> 
void hannuota(int n, char A, char B, char C);

int main(){
                char ch1 = 'A';
                char ch2 = 'B';
                char ch3 = 'C';
                int n;
        
                printf("请输入要移动盘子的个数: ");
                scanf("%d", &n);
        
                hannuota(n, ch1, ch2, ch3);
}

void hannuota(int n, char A, char B, char C)
{
        //A,B,C并非柱子,是A借助B传给C
                /*        
                如果是一个盘子
                                直接将 A 柱子上的盘子移动到 C柱子上面
                否则
                                先将 A 柱子上的 n-1 个盘子借助 C 移动到B上面
                                直接将 A 柱子上的第 n 个盘子移动到上C上面
                                最后将 B 柱子上面的n-1个盘子借助 A 移动到 C 上
                */
        if(1 == n)
        {
                printf("将编号为 %d 的盘子,直接从 %c 柱子,移动到 %c的柱子上面\n",n,A,C);
        }
        else
        {
                hannuota(n-1,A,C,B);
                printf("将编号为 %d的盘子,直接从 %c 柱子,移动到 %c的柱子上面\n",n,A,C);
                hannuota(n-1,B,A,C);        
        }
}

非线性结构

定义

专业定义:

树的应用

树是数据库中数据组织的一种重要形式
操作系统子父进程的关系本身就是一棵树
面向对象语言中类的继承关系
赫夫曼树

链式二叉树借助容器

#include <bits/stdc++.h>
using namespace std;

typedef struct node {
    int data;
    node* left;
    node* right;
    node(int val) : data(val), left(nullptr), right(nullptr) {}
} * PNODE;

// 利用数组层序建树
PNODE buildTree(vector<int>& v, int index) {
    if (index >= v.size()|| v[index] == -1) {
        return nullptr; //
    }
    PNODE root = new node(v[index]);

    root->left = buildTree(v, index*2+1);
    root->right = buildTree(v, index*2+2);

    return root;
}

// 层序输出
void leveltravers(PNODE root) {
    if (!root) return;
    queue <node *> q;
    q.push(root);
    while(!q.empty()){
        node * tmp = q.front();
        q.pop();
        cout << tmp->data;
        if (tmp->left) q.push(tmp->left);
        if (tmp->right) q.push(tmp->right);
    }

}

// 先序遍历
void pretraversal(PNODE& root) {
    if (root) {
        cout << root->data << endl;
        pretraversal(root->left);
        pretraversal(root->right);
    }
}

// 中序遍历
void intraversal(PNODE& root) {
    if (root) {
        intraversal(root->left);
        cout << root->data << endl;
        intraversal(root->right);
    }
}

// 后序遍历
void posttraversal(PNODE& root) {
    if (root) {
        posttraversal(root->left);
        posttraversal(root->right);
        cout << root->data << endl;
    }
}

//返回的值在叶子处 比如叶子结点 返回0+自身的深度
int getDepth(node * t){
    if (!t) return 0;
    else{
        int m = getDepth(t->left);
        int n = getDepth(t->right);
        return m > n ? m + 1: n + 1;
    }
}

//遇到空的返回0 比如叶子结点 加自身的1;
int nodeCount(node * t){
    if(!t) return 0;
    else return nodeCount(t->left) + nodeCount(t->right) +1;

}

int leafCout(node * t){
    if (!t) return 0;
    if (t->right == nullptr && t->right == nullptr) return 1;
    else return leafCout(t->left) + leafCout(t->right);
}


int main() {
    vector<int> v;
    int n, tmp;
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> tmp;
        v.push_back(tmp);
    }
    PNODE root = buildTree(v, 0);

    cout << "层序遍历" << endl;
    leveltravers(root);
    cout << "先序遍历" << endl;
    pretraversal(root);
    cout << "中序遍历" << endl;
    intraversal(root);
    cout << "后序遍历" << endl;
    posttraversal(root);
    cout << "结点的数量"<<endl;
    cout << nodeCount(root)<<endl;
    cout << "树的深度"<<endl;
    cout << getDepth(root)<<endl;
    cout << "叶子的数量"<<endl;
    cout << leafCout(root) << endl;
    return 0;
}

查找

二分查找

左闭右闭

int search(int nums[], int size, int target) //nums是数组,size是数组的大小,target是需要查找的值
{
    int left = 0;
    int right = size - 1;        // 定义了target在左闭右闭的区间内,[left, right]
    while (left <= right) {        //当left == right时,区间[left, right]仍然有效
        int middle = left + ((right - left) / 2);//等同于 (left + right) / 2,防止溢出
        if (nums[middle] > target) {
            right = middle - 1;        //target在左区间,所以[left, middle - 1]
        } else if (nums[middle] < target) {
            left = middle + 1;        //target在右区间,所以[middle + 1, right]
        } else {        //既不在左边,也不在右边,那就是找到答案了
            return middle;
        }
    }
    //没有找到目标值
    return -1;
}

左闭右开

int search(int nums[], int size, int target)
{
        int left = 0;
        int right = size; //定义target在左闭右开的区间里,即[left, right)
        while (left < right) {        //因为left = right的时候,在[left, right)区间上无意义
                int middle = left + ((right - left) / 2);
                if (nums[middle] > target) {
                        right = middle; //target 在左区间,在[left, middle)中 
                } else if (nums[middle] < target) {
                        left = middle + 1;
                } else {
                        return middle;
                }
        } 
    // 没找到就返回-1
        return -1;
}
posted @ 2024-02-08 02:10  江寒雨  阅读(29)  评论(0)    收藏  举报