手记

基础算法合集(未完待续...)

桶排序

#pragma mark - 桶排序
    printf("桶排序\n");    //比较0~10之间的数则创建一个长度11的数组
    int a[11];    //初始化,全部归0
    for (int i = 0; i < 11; i ++) {
        a[i] = 0;
    }    //读入5个数,记录每个数出现的次数
    for (int i = 0; i < 5; i++) {        int t;        scanf("%d",&t);
        a[t]++;
    }    //按顺序将角标输出(角标即为排序的数),个数是几就输出几次
    for (int i = 0; i < 11; i ++) {        for (int j = 1; j <= a[i]; j ++) {            printf("%d\n",i);
        }
    }

冒泡排序

#pragma mark - 冒泡排序
    printf("冒泡排序\n");    //比较5个数,创建一个长度为5的数组
    int b[5];    //读入5个数
    for (int i = 0; i < 5; i ++) {        scanf("%d",&b[i]);
    }    //排序
    //5个数只需要冒泡四次
    for (int i = 0; i < 5-1; i ++) {        for (int j = 0; j < 5-i; j ++) {            if (b[j]<b[j+1]) {                //两个数比较,如果后面的数大于前面的数,则两个数交换(冒泡)
                int t;
                t = b[j];
                b[j] = b[j+1];
                b[j+1] = t;
            }
        }
    }    //按顺序输出
    for (int i = 0; i < 5; i ++) {        printf("%d\n",b[i]);
    }

快速排序

#pragma mark - 快速排序//定义一个全局数组用于排序10个数int a[10];//快速排序函数void quicksort(int left,int right){    if (right<left) {        return;
    }    //让i,j分别等于左右两边的下标,让最左的数作为基数
    int i = left,j = right,temp = a[left],t;    /*
     1.先j向左移动,直到找到比temp小的数,然后让i向右移动,直到找到比temp大的数,然后将这两个数交换位置。由于基数为最左端的数,所以一定要让j先向左移动
     2.继续移动i,j,重复步骤1,直到i,j相等,将基数放于i位置
     3.从基数处分为两组,分别执行步骤1、2、3
     */
    while (i != j) {        //先让j向左移动
        while (a[j]>=temp && i<j) {
            j --;
        }        //再让i向右移动
        while (a[i]<=temp && i<j) {
            i ++;
        }        //找到比基数小的数与比基数大的数,交换
        if (i < j) {
            t = a[i];
            a[i] = a[j];
            a[j] = t;
        }
    }    //i,j相等,将基数与i位置的数交换
    a[left] = a[i];
    a[i] = temp;    //分成两组,继续操作
    quicksort(left, i-1);
    quicksort(i+1, right);
}int main(int argc, const char * argv[]) {    
    //读入十个数
    for (int i = 0; i < 10; i ++) {        scanf("%d",&a[i]);
    }    
    //执行排序函数
    quicksort(0, 9);    
    for (int i = 0; i < 10; i ++) {        printf("%d\n",a[i]);
    }    
    return 0;
}

队列与出入队

#pragma mark - 队列与出入队列//定义一个队列struct queue {
    int data[100];  //队列主体,存储数据
    int head;  //队首
    int tail;  //队尾};int main(int argc, const char * argv[]) {    
    struct queue q;  //初始化一个队列
    //初始化
    q.head = 0;
    q.tail = 0;    //输入9个数
    for (int i = 0; i < 9; i ++) {        scanf("%d",&q.data[q.tail]);
        q.tail ++;
    }    //空队列时停止循环
    while (q.head < q.tail) {        //打印队首,并出队
        printf("%d\n",q.data[q.head]);
        q.head ++;        //将新队首添加到队尾
        q.data[q.tail] = q.data[q.head];
        q.tail ++;        //再将队首出队
        q.head ++;
    }    
    return 0;
}

判断回文(栈操作)

#pragma mark - 判断字符串是否为回文
    char a[100], s[100];    long len, next, top, mid;    //输入一串字符
    gets(a);
    len = strlen(a);    //找出中点
    mid = len/2-1;    //初始化栈
    top = 0;    //将中点前的字符入栈
    for (int i = 0; i<= mid; i ++) {
        top ++;
        s[top] = a[i];
    }    //判断奇偶,来确定开始对比的位置
    if (len%2 == 0) {
        next = mid + 1;
    }    else {
        next = mid + 2;
    }    //对比,对比成功一位出栈一位
    for (long i = next; i < len; i ++) {        if (s[top] != a[i]) {            break;
        }        //出栈操作
        top --;
    }    
    if (top == 0) {        printf("y\n");
    }    else {        printf("n\n");
    }

链表-插入一个数据

#pragma mark - 链表操作-插入一个数据//定义链表的节点struct node {
    int data;  //节点的数据
    struct node *next;  //指向下一个节点的指针};int main(int argc, const char * argv[]) {    
    struct node *head, *p, *q, *t;
    //读入5个数
    int a;
    head = NULL;
    q = NULL;    for (int i = 0; i < 5; i ++) {        scanf("%d",&a);        //创建一个节点
        p = malloc(sizeof(struct node));
        p->data = a;
        p->next = NULL;        if (head == NULL) {            //如果头节点的指针为空,说明这是一个空链表,将新创建的节点作为头节点
            head = p;
        }        else {            //头节点不为空,则说明这不是一个空链表,则将新创建的节点作为上一个节点的下一个节点
            q->next = p;
        }        //将新创建的节点作为上一个节点,进行下一次循环
        q = p;
    }    //插入
    scanf("%d",&a);    //循环遍历,直到找到一个比输入的数大的节点,插入到它前面
    t = head;    while (t != NULL) {        if (t->next->data > a) {            //创建一个新的节点
            p = malloc(sizeof(struct node));
            p->data = a;            //插入这个节点
            p->next = t->next;
            t->next = p;            break;
        }
        t = t->next;
    }    //遍历
    t = head;    while (t != NULL) {        printf("%d\n",t->data);
        t = t->next;
    }    
    return 0;
}

“模拟链表” 的实现与操作(插入数据)

#pragma mark - “模拟链表”的实现与操作(插入一个数)
    /*
     模拟链表:有两个整形数组,第一个整型数组 data 是用来存放序列中具体数字的,另外一个整型 数组 right 是用来存放当前序列中每一个元素右边的元素在数组 data 中位置的。例如 right[1] 的值为 2,就表示当前序列中 1 号元素右边的元素存放在 data[2]中;如果是 0,例如 right[9] 的值为 0,就表示当前序列中 9 号元素的右边没有元素。
     */
    //定义两个数组
    int data[100], right[100];    int n, len, t;    //读入几个数
    scanf("%d",&n);    for (int i = 1; i <= n; i ++) {        scanf("%d",&data[i]);
    }    //初始化right数组
    len = n;    for (int i = 1; i <= n; i ++) {        if (i != len) {            //如果“模拟链表”中第 i 位不是最后一位,则在“模拟链表”中第 i 位的右边一位在 data 中的位置为 i+1
            right[i] = i+1;
        }        else {            //i 是最后一位,则“模拟链表”中第 i 位的右边一位在
            right[i] = 0;
        }
    }    //插入一个数据,直接将数据放在 data 的最后
    len ++;    scanf("%d",&data[len]);    //遍历链表,直到找到一个比输入数大的数
    t = 1;    while (t != 0) {        //如果链表中 t 位置的下一位的值大于刚刚输入的数,则进行插入操作
        if (data[right[t]] > data[len]) {
            right[len] = right[t];
            right[t] = len;            break;
        }        //t 等于链表中 t 位置的下一位
        t = right[t];
    }    
    //遍历
    t = 1;    while (t != 0) {        printf("%d\n",data[t]);
        t = right[t];
    }

广度优先搜索与深度优先搜索

//以一个 10 * 10 的二维矩阵为例,搜索矩阵中一个点周围的大于0的点个数/**
 广度优先搜索
 *///表示一个点的结构体struct note {
    int x;    int y;
};int main(int argc, const char * argv[]) {    struct note que[101];  //表示存储点的队列,在 10*10 的二维矩阵中最多 101 个点
    int head,tail;  //指示队列的队首与队尾
    int a[11][11];  //用来表示二维矩阵
    int book[11][11] = {0};  //用来标识已经入队的点,例:(2,3) 已经在队列中,则 book[2][3] = 1
    int i,j,sum,startx,starty,tx,ty;    
    //定义一个方向数组,用来表示向上下左右搜索
    int next[4][2] = {
        {0,1},   //向右
        {1,0},   //向下
        {0,-1},  //向左
        {-1,0}   //向上
    };    
    //设置开始搜索的点
    startx = 6;
    starty = 8;    
    //读入一个二维矩阵
    for (i = 1; i <= 10; i ++)        for (j = 1; j <= 10; j ++)            scanf("%d",&a[i][j]);    
    //初始化队列
    head = 1;
    tail = 1;    //将开始点添加进队列
    que[tail].x = startx;
    que[tail].y = starty;
    tail ++;
    book[startx][starty] = 1;
    sum = 1;    
    //队列不为空就循环
    while (head < tail) {        //遍历四个方向
        for (i = 0; i < 4; i ++) {            //计算下一步的坐标
            tx = que[head].x + next[i][0];
            ty = que[head].y + next[i][1];            //判断是否越界
            if (tx<1 || tx>10 || ty>10 || ty<1)                continue;            //判断是否已经走过这个点且符合条件(这个矩阵上的点的值大于0)
            if (a[tx][ty]>0 && book[tx][ty]==0) {
                sum ++;
                book[tx][ty] = 1;  //标记这个点已经走过
                
                //入队
                que[tail].x = tx;
                que[tail].y = ty;
                tail ++;
                
            }
        }        //这个点的四个方向都遍历完了,转向下一个点,继续遍历这个点的四个方向(广度优先)
        head ++;
    }    
    //输出符合条件的点的总和
    printf("%d\n",sum);    
    return 0;
}/**
 深度优先搜索
 */int a[11][11];  //用来表示二维矩阵int book[11][11] = {0};  //用来标识已经入队的点,例:(2,3) 已经在队列中,则 book[2][3] = 1int sum;void dfs(int x, int y){    
    //定义一个方向数组,用来表示向上下左右搜索
    int next[4][2] = {
        {0,1},   //向右
        {1,0},   //向下
        {0,-1},  //向左
        {-1,0}   //向上
    };    int i,tx,ty;    
    //遍历四个方向
    for (i = 0; i < 4; i ++) {        //计算下一个点坐标
        tx = x + next[i][0];
        ty = y + next[i][1];        //判断是否越界
        if (tx<1 || tx>10 || ty>10 || ty<1)            continue;        //判断是否已经走过这个点且符合条件(这个矩阵上的点的值大于0)
        if (a[tx][ty]>0 && book[tx][ty]==0) {
            sum ++;
            book[tx][ty] = 1;  //这个点已经走过
            dfs(tx, ty);  //继续下一个点(深度优先)
        }
    }    
    //已经到了一个方向的终点,返回上一个点继续另一个方向(深度优先)
    return;
    
}int main(int argc, const char * argv[]) {    
    int i,j,startx,starty;    
    //设置开始点
    startx = 6;
    starty = 8;    
    //读入一个二维矩阵
    for (i = 1; i <= 10; i ++)        for (j = 1; j <= 10; j ++)            scanf("%d",&a[i][j]);    
    //记录开始位置已经读取过
    book[startx][starty] = 1;
    sum = 1;    
    //开始搜索
    dfs(startx, starty);    
    printf("%d\n",sum);    
    return 0;
}



作者:i_have_an_Apple
链接:https://www.jianshu.com/p/c2df48cca280


0人推荐
随时随地看视频
慕课网APP