• 数据结构算法代码


    本文总结了关于BF算法、strassen矩阵乘法、TSP问题、大整数乘法、堆排序、多元最短路径、汉诺塔等常见的16种基本算法代码,编程语言采用C/C++实现,通过,经测试编译均能希望对初学算法的人能有所帮助。

    BF算法

    #include <iostream>
    #include <string>
    using namespace std;
    int BF_Find(string &s, string &t)
    {
        int i = 0, j = 0, count = 0;
        while(i < s.size())
        {
    
            if(s.at(i) == t.at(j))
            {
                i++;
                j++;
                count++;
            }
            else
            {
                i++;
                j = 0;
                count = 0;
            }
            if(count == t.size())
            {
                cout << "模式匹配成功,起始位置是:" << i - count + 1 << endl;
                return (i - count + 1);
            }
    
        }
        cout << "字符串匹配失败!" << endl;
        return 0;
    }
    int main()
    {
        string str1, str2;
        cout << "请输入主串:" << endl;
        cin >> str1;
        cout << "请输入子串:" << endl;
        cin >> str2;
        BF_Find(str1, str2);
        return 0;
    }
    

    strassen矩阵乘法

    #include <iostream.h>
    
    const int N = 8; //常量N用来定义矩阵的大小
    
    void main()
    {
    
        void STRASSEN(int n, float A[][N], float B[][N], float C[][N]);
        void input(int n, float p[][N]);
        void output(int n, float C[][N]);                   //函数声明部分
    
        float A[N][N], B[N][N], C[N][N]; //定义三个矩阵A,B,C
    
        cout << "现在录入矩阵A[N][N]:" << endl << endl;
        input(N, A);
        cout << endl << "现在录入矩阵B[N][N]:" << endl << endl;
        input(N, B);                        //录入数组
    
        STRASSEN(N, A, B, C); //调用STRASSEN函数计算
    
        output(N, C); //输出计算结果
    }
    
    
    void input(int n, float p[][N]) //矩阵输入函数
    {
        int i, j;
    
        for(i = 0; i < n; i++)
        {
            cout << "请输入第" << i + 1 << "行" << endl;
            for(j = 0; j < n; j++)
                cin >> p[i][j];
        }
    }
    
    void output(int n, float C[][N]) //据矩阵输出函数
    {
        int i, j;
        cout << "输出矩阵:" << endl;
        for(i = 0; i < n; i++)
        {
            cout << endl;
            for(j = 0; j < n; j++)
                cout << C[i][j] << "  ";
        }
        cout << endl << endl;
    
    }
    
    void MATRIX_MULTIPLY(float A[][N], float B[][N], float C[][N]) //按通常的矩阵乘法计算C=AB的子算法(仅做2阶)
    {
        int i, j, t;
        for(i = 0; i < 2; i++)               //计算A*B-->C
            for(j = 0; j < 2; j++)
            {
                C[i][j] = 0;                 //计算完一个C[i][j],C[i][j]应重新赋值为零
                for(t = 0; t < 2; t++)
                    C[i][j] = C[i][j] + A[i][t] * B[t][j];
            }
    }
    
    void MATRIX_ADD(int n, float X[][N], float Y[][N], float Z[][N]) //矩阵加法函数X+Y—>Z
    {
        int i, j;
        for(i = 0; i < n; i++)
            for(j = 0; j < n; j++)
                Z[i][j] = X[i][j] + Y[i][j];
    }
    
    void MATRIX_SUB(int n, float X[][N], float Y[][N], float Z[][N]) //矩阵减法函数X-Y—>Z
    {
        int i, j;
        for(i = 0; i < n; i++)
            for(j = 0; j < n; j++)
                Z[i][j] = X[i][j] - Y[i][j];
    
    }
    
    
    void STRASSEN(int n, float A[][N], float B[][N], float C[][N]) //STRASSEN函数(递归)
    {
        float A11[N][N], A12[N][N], A21[N][N], A22[N][N];
        float B11[N][N], B12[N][N], B21[N][N], B22[N][N];
        float C11[N][N], C12[N][N], C21[N][N], C22[N][N];
        float M1[N][N], M2[N][N], M3[N][N], M4[N][N], M5[N][N], M6[N][N], M7[N][N];
        float AA[N][N], BB[N][N], MM1[N][N], MM2[N][N];
    
        int i, j; //,x;
    
    
        if (n == 2)
            MATRIX_MULTIPLY(A, B, C); //按通常的矩阵乘法计算C=AB的子算法(仅做2阶)
        else
        {
            for(i = 0; i < n / 2; i++)
                for(j = 0; j < n / 2; j++)
    
                {
                    A11[i][j] = A[i][j];
                    A12[i][j] = A[i][j + n / 2];
                    A21[i][j] = A[i + n / 2][j];
                    A22[i][j] = A[i + n / 2][j + n / 2];
                    B11[i][j] = B[i][j];
                    B12[i][j] = B[i][j + n / 2];
                    B21[i][j] = B[i + n / 2][j];
                    B22[i][j] = B[i + n / 2][j + n / 2];
                }                                   //将矩阵A和B式分为四块
    
    
    
    
            MATRIX_SUB(n / 2, B12, B22, BB);
    
            STRASSEN(n / 2, A11, BB, M1); //M1=A11(B12-B22)
    
            MATRIX_ADD(n / 2, A11, A12, AA);
            STRASSEN(n / 2, AA, B22, M2); //M2=(A11+A12)B22
    
            MATRIX_ADD(n / 2, A21, A22, AA);
            STRASSEN(n / 2, AA, B11, M3); //M3=(A21+A22)B11
    
            MATRIX_SUB(n / 2, B21, B11, BB);
            STRASSEN(n / 2, A22, BB, M4); //M4=A22(B21-B11)
    
            MATRIX_ADD(n / 2, A11, A22, AA);
            MATRIX_ADD(n / 2, B11, B22, BB);
            STRASSEN(n / 2, AA, BB, M5); //M5=(A11+A22)(B11+B22)
    
            MATRIX_SUB(n / 2, A12, A22, AA);
            MATRIX_SUB(n / 2, B21, B22, BB);
            STRASSEN(n / 2, AA, BB, M6); //M6=(A12-A22)(B21+B22)
    
            MATRIX_SUB(n / 2, A11, A21, AA);
            MATRIX_SUB(n / 2, B11, B12, BB);
            STRASSEN(n / 2, AA, BB, M7); //M7=(A11-A21)(B11+B12)
            //计算M1,M2,M3,M4,M5,M6,M7(递归部分)
    
    
            MATRIX_ADD(N / 2, M5, M4, MM1);
            MATRIX_SUB(N / 2, M2, M6, MM2);
            MATRIX_SUB(N / 2, MM1, MM2, C11); //C11=M5+M4-M2+M6
    
            MATRIX_ADD(N / 2, M1, M2, C12); //C12=M1+M2
    
            MATRIX_ADD(N / 2, M3, M4, C21); //C21=M3+M4
    
            MATRIX_ADD(N / 2, M5, M1, MM1);
            MATRIX_ADD(N / 2, M3, M7, MM2);
            MATRIX_SUB(N / 2, MM1, MM2, C22); //C22=M5+M1-M3-M7
    
            for(i = 0; i < n / 2; i++)
                for(j = 0; j < n / 2; j++)
                {
                    C[i][j] = C11[i][j];
                    C[i][j + n / 2] = C12[i][j];
                    C[i + n / 2][j] = C21[i][j];
                    C[i + n / 2][j + n / 2] = C22[i][j];
                }                                            //计算结果送回C[N][N]
    
        }
    
    }
    
    
    /*假定strassen矩阵分割方案仅用于n≥8的矩阵乘法,而对于n<8的矩阵乘法则直接利用公式进行计算。则n= 8时,8×8矩阵相乘需要7次4×4矩阵乘法和1 8次4×4矩阵加/减法。每次矩阵乘法需花费6 4m+ 4 8a次操作,每次矩阵加法或减法需花费1 6a次操作。因此总的操作次数为7 ( 6 4m+ 4 8a) + 1 8 ( 1 6a) = 4 4 8m+ 6 2 4a。而使用直接计算方法,则需要5 1 2m+ 4 4 8a次操作。要使S t r a s s e n方法比直接计算方法快,至少要求5 1 2-4 4 8次乘法的开销比6 2 4-4 4 8次加/减法的开销大。或者说一次乘法的开销应该大于近似2 . 7 5次加/减法的开销。
    
    假定n<1 6的矩阵是一个“小”问题,strassen的分解方案仅仅用于n≥1 6的情况,对于n<1 6的矩阵相乘,直接利用公式。则当n= 1 6时使用分而治之算法需要7 ( 5 1 2m+ 4 4 8a) +1 8 ( 6 4a) = 3 5 8 4m+ 4 2 8 8a次操作。直接计算时需要4 0 9 6m+ 3 8 4 0a次操作。若一次乘法的开销与一次加/减法的开销相同,则strassen方法需要7872次操作及用于问题分解的额外时间,而直接计算方法则需要7936次操作加上程序中执行for循环以及其他语句所花费的时间。即使直接计算方法所需要的操作次数比strassen方法少,但由于直接计算方法需要更多的额外开销,因此它也不见得会比strassen方法快。
    
    n 的值越大,Strassen 方法与直接计算方法所用的操作次数的差异就越大,因此对于足够大的n,Strassen 方法将更快。设t (n) 表示使用Strassen 分而治之方法所需的时间。因为大的矩阵会被递归地分割成小矩阵直到每个矩阵的大小小于或等于k(k至少为8,也许更大,具体值由计算机的性能决定). 用迭代方法计算,可得t(n) = (nlog27)。因为log27 ≈2 . 8 1,所以与直接计算方法的复杂性(n3)相比,分而治之矩阵乘法算法有较大的改进。
    
    再次说明:
    
    矩阵C = AB,可写为
    C11 = A11B11 + A12B21
    C12 = A11B12 + A12B22
    C21 = A21B11 + A22B21
    C22 = A21B12 + A22B22
    如果A、B、C都是二阶矩阵,则共需要8次乘法和4次加法。如果阶大于2,可以将矩阵分块进行计算。耗费的时间是O(nE3)。
    
    要改进算法计算时间的复杂度,必须减少乘法运算次数。按分治法的思想,Strassen提出一种新的方法,用7次乘法完成2阶矩阵的乘法,算法如下:
    M1 = A11(B12 - B12)
    M2 = (A11 + A12)B22
    M3 = (A21 + A22)B11
    M4 = A22(B21 - B11)
    M5 = (A11 + A22)(B11 + B22)
    M6 = (A12 - A22)(B21 + B22)
    M7 = (A11 - A21)(B11 + B12)
    完成了7次乘法,再做如下加法:
    C11 = M5 + M4 - M2 + M6
    C12 = M1 + M2
    C21 = M3 + M4
    C22 = M5 + M1 - M3 - M7
    全部计算使用了7次乘法和18次加减法,计算时间降低到O(nE2.81)。计算复杂性得到较大改进。
    */

    TSP问题

    #include <iostream>
    #include <list>
    using namespace std ;
    
    typedef list<int> LISTINT;
    
    LISTINT listAnother;
    LISTINT list_result;
    
    int d[4][4] = {{ -1, 3, 6, 7}, {2, -1, 8, 6}, {7, 3, -1, 5,}, {7, 3, 7, -1}}; //路径权值
    int matrix_length = 4;
    
    int getPath(int n, LISTINT list_org)
    {
    
        LISTINT::iterator i;
    
        int minValue;
        if(n == 1)
        {
            i = list_org.begin();
            minValue = d[*i - 1][0];
            if(list_org.size() == matrix_length - 1)
            {
                list_result = list_org;
            }
        }
        else
        {
            int temp;
            i = list_org.begin();
            temp = *i;
            list_org.erase(i);
            i = list_org.begin();
            minValue = d[temp - 1][*(i) - 1] + getPath(n - 1, list_org);
            if(list_org.size() == matrix_length - 1)
            {
                list_result = list_org;
            }
    
            for(int j = 2; j < n; j++)
            {
                i = list_org.begin();
                for(int k = 1; k < j; k++)
                {
                    i++;
                }
    
                int tempvalue = *i;
                list_org.erase(i);
                list_org.push_front(tempvalue);
                i = list_org.begin();
                tempvalue = d[temp - 1][*(i) - 1] + getPath(n - 1, list_org);
    
                if(tempvalue < minValue)
                {
                    if(list_org.size() == matrix_length - 1)
                    {
                        list_result = list_org;
                    }
                    minValue = tempvalue;
                }
    
            }
        }
        return minValue;
    }
    int main(int argc, char *argv[])
    {
    
        LISTINT list_org;
        LISTINT::iterator h;
        list_org.push_front(4);
        list_org.push_front(3);
        list_org.push_front(2);
        list_org.push_front(1);
        cout << "旅行商问题动态规划算法" << endl;
        cout << "路线长度的矩阵表示如下 (-1表示无限大)" << endl;
        for(int j = 0; j < matrix_length; j++)
        {
            cout << endl;
            for(int k = 0; k < matrix_length; k++)
            {
                cout << " " << d[j][k];
            }
        }
        cout << endl;
    
    
        cout << "计算结果:" << getPath(4, list_org) << endl;
        list_result.push_front(1);
        list_result.push_back(1);
        cout << "要走的路径:---->:";
        for (h = list_result.begin(); h != list_result.end(); ++h)
    
            cout << *h << " ";
    
    
        cout << endl;
        int i;
        cin >> i;
        return 0;
    }
    

    大整数乘法

    #define MAXLENGTH 1000
    #include <stdio.h>
    #include <string.h>
    
    void compute(char *a, char *b, char *c);
    
    void main(void)
    {
        char a[MAXLENGTH], b[MAXLENGTH], c[MAXLENGTH * 2];
    
        puts("Input multiplier :");
        gets(a);
        puts("Input multiplicand :");
        gets(b);
    
        compute(a, b, c);
    
        puts("Answer :");
        puts(c);
        getchar();
    }
    
    void compute(char *a, char *b, char *c)
    {
        int i, j, m, n;
        long sum, carry;
    
        m = strlen(a) - 1;
        n = strlen(b) - 1;
        for (i = m; i >= 0; i--)
            a[i] -= '0';
        for (i = n; i >= 0; i--)
            b[i] -= '0';
        c[m + n + 2] = '';
    
        carry = 0;
        for (i = m + n; i >= 0; i--) /* i 为坐标和 */
        {
            sum = carry;
    
            if ((j = i - m) < 0)
                j = 0;
            for ( ; j <= i && j <= n; j++) /* j 为纵坐标 */
                sum += a[i - j] * b[j]; /* 累计一组数的和 */
    
            c[i + 1] = sum % 10 + '0'; /* 算出保留的数字 */
            carry = sum / 10; /* 算出进位 */
    
        }
    
        if ((c[0] = carry + '0') == '0') /* if no carry, */
            c[0] = '40'; /* c[0] equals to space */
    }
    

    堆排序

    #include<iostream>
    using namespace std;
    
    template<class T> //类型不限
    void HeapAdjust(T A[], int a, int z)
    {
        for(int i = a, j = 2 * i; j <= z; i = j, j = 2 * i) //i为父,j为子
        {
            if(j < z && A[j + 1] > A[j]) j++; //大顶堆,沿大孩子方向下行
            if(A[i] < A[j])
                swap(A[i], A[j]);
            else
                break;
        }
    }
    
    template<class T>
    void HeapSort(T A[], int n)
    {
        for(int i = n / 2; i >= 1; i--) //从倒数第一个非叶子结点,自下而上堆化
            HeapAdjust(A, i, n);
        for(i = n; i > 1; i--) //交换A[1]与最后元素A[i](i=n, ..., 1), 再堆化
        {
            swap(A[1], A[i]);
            HeapAdjust(A, 1, i - 1);
        }
    }
    
    int main()
    {
        int len = 5;
        int A[] = {0, 9, 7, 5, 6, 4};
    
        HeapSort(A, len);
    
        for(int i = 1; i <= len; i++)
            cout << A[i] << ' ';
        cout << endl;
        return 0;
    }

    多元最短路径

    #include"stdio.h"
    #define Maxv 100
    #define INF 100000
    void ppath(int path[][Maxv], int i, int j)
    {
        int k;
        k = path[i][j];
        if(k == -1)return;
        ppath(path, i, k);
        printf("%d,", k);
        ppath(path, k, j);
    }
    void Dispath(int A[][Maxv], int path[][Maxv], int n)
    {
        int i, j;
        for(i = 0; i < n; i++)
            for(j = 0; j < n; j++)
            {
                if(A[i][j] != INF && A[i][j] != 0)
                {
                    printf("从%d%d的路径为:", i, j);
                    printf("%d,", i);
                    ppath(path, i, j);
                    printf("%d", j);
                    printf("路径长度为:%d
    ", A[i][j]);
                }
            }
    }
    void Flofd(int A[][Maxv], int n)
    {
        int i, j, k, path[Maxv][Maxv];
        for(i = 0; i < n; i++)
            for(j = 0; j < n; j++)
                path[i][j] = -1;
        for(k = 0; k < n; k++)
            for(i = 0; i < n; i++)
                for(j = 0; j < n; j++)
                    if(A[i][j] > A[i][k] + A[k][j])
                    {
                        A[i][j] = A[i][k] + A[k][j];
                        path[i][j] = k;
                    }
        Dispath(A, path, n);
    }
    int main()
    {
        int n = 4, path[Maxv][Maxv];
        int A[][Maxv] = {{0, 5, INF, 7},
            {INF, 0, 4, 2},
            {3, 3, 0, 2},
            {INF, INF, 1, 0}
        };
        Flofd(A, n);
    }

    汉诺塔

    #include"stdio.h"
    #define Maxv 100
    #define INF 100000
    void ppath(int path[][Maxv], int i, int j)
    {
        int k;
        k = path[i][j];
        if(k == -1)return;
        ppath(path, i, k);
        printf("%d,", k);
        ppath(path, k, j);
    }
    void Dispath(int A[][Maxv], int path[][Maxv], int n)
    {
        int i, j;
        for(i = 0; i < n; i++)
            for(j = 0; j < n; j++)
            {
                if(A[i][j] != INF && A[i][j] != 0)
                {
                    printf("从%d到%d的路径为:", i, j);
                    printf("%d,", i);
                    ppath(path, i, j);
                    printf("%d", j);
                    printf("路径长度为:%dn", A[i][j]);
                }
            }
    }
    void Flofd(int A[][Maxv], int n)
    {
        int i, j, k, path[Maxv][Maxv];
        for(i = 0; i < n; i++)
            for(j = 0; j < n; j++)
                path[i][j] = -1;
        for(k = 0; k < n; k++)
            for(i = 0; i < n; i++)
                for(j = 0; j < n; j++)
                    if(A[i][j] > A[i][k] + A[k][j])
                    {
                        A[i][j] = A[i][k] + A[k][j];
                        path[i][j] = k;
                    }
        Dispath(A, path, n);
    }
    int main()
    {
        int n = 4, path[Maxv][Maxv];
        int A[][Maxv] = {{0, 5, INF, 7},
            {INF, 0, 4, 2},
            {3, 3, 0, 2},
            {INF, INF, 1, 0}
        };
        Flofd(A, n);
    }
    /*
    首先你得知道原理:
    N个汉诺塔问题可以转换成:
    1 先把N-1个塔从A搬到B.
    2 把最下面的盘搬到C
    3 把N-1个盘从B搬到C
    
    上面的程序就是利用这个原理:
    假若有4个盘子:
    hanoi( 4, 'A', 'B', 'C' )
    会执行:
    4不等于1,所以执行else =>
    hanoi( 4- 1, 'A', 'C', 'B' );    .....1
    
    move( 'A','C' );                   .....2
    
    hanoi( 4 - 1, 'B','A', 'C' );      ......3
    在执行第1句时,调用递归:
    hanoi( 3, 'A', 'C', 'B' ); 这个又调用hanoi函数:
    3不等于1,所以执行else =>
    hanoi( 3- 1, 'A' ,'B','C' );    .....4 
    move( 'A','B');                   .....5
    hanoi( 3 - 1, 'C','A', 'B' );      ......6
    在执行第4句时,调用递归:
    hanoi( 2, 'A' ,'B','C' );这个又调用hanoi函数:
    2不等于1,所以执行else =>
    hanoi( 2- 1, 'A','C','B');    .....7
    move( 'A','C');                   .....8
    hanoi( 2 - 1, 'B','A','C');      ......9
    执行第7句时,调用递归:
    hanoi( 1, 'A','C','B');这个又调用hanoi函数:
    等于1,打印A-->B,此次调用完毕,转到第8句,
    打印A->C,再执行第9句:
    hanoi( 1, 'B','A','C');
    等于1,所以move(one,three),即B->C
    注意,这时候又回到了第5句(因为第4句包含的7,8,9全部执行完了):B-A要看懂递归程序,往往应先从最简单情况看起。先看hanoi(1, one, two, three)的情况。这时直接将one柱上的一个盘子搬到three柱上。注意,这里one柱或three柱到底是AB还是C并不重要,要记住的是函数第二个参数代表的柱上的一个盘被搬到第四个参数代表的柱上。为方便,将这个动作记为:one =》three再看hanoi(2, one, two, three)的情况。考虑到hanoi(1)的情况已经分析过了,可知这时实际上将产生三个动作,分别是:one =》twoone =》threetwo =》three很显然,这实际上相当于将one柱上的两个盘直接搬到three柱上。再看hanoi(3, one, two, three)的情况。分析hanoi(2, one , three, two)one =》threehanoi(2, two, one, three)即:先将one柱上的两个盘搬到two柱上,再将one柱上的一个盘搬到three柱上,最后再将two柱上的两个盘搬到three柱上。这不就等于将one柱上的三个盘直接搬到three柱上吗?运用归纳法可知,对任意nhanoi(n-1, one , three, two)one =》threehanoi(n-1, two, one, three)就是先将one柱上的n-1个盘搬到two柱上,再将one柱上的一个盘搬到three柱上,最后再将two柱上的n-1个盘搬到three柱上。这就是我们所需要的结果!
    */

    快速排序

    #include<iostream>
    using namespace std;
    
    long i, j, k, x, y, z, n;
    long a[10001];
    
    void qsort(long l, long r)
    {
        long i = l, j = r, x = a[(l + r) / 2], y;
        do
        {
            while(a[i] < x)i++;
            while(a[j] > x)j--;
            if(i <= j)
            {
                y = a[i];
                a[i] = a[j];
                a[j] = y;
                i++;
                j--;
            }
        }
        while(i < j);
        if(i < r)qsort(i, r);
        if(j > l)qsort(l, j);
    }
    
    int main()
    {
        cin >> n;
        for(i = 1; i <= n; i++)cin >> a[i];
        qsort(1, n);
        for(i = 1; i <= n; i++)cout << a[i] << ' ';
        cout << endl;
        system("pause");
        return 0;
    }

    归并排序

    #include<stdio.h>
    
    // 一个递归函数
    void mergesort(int *num, int start, int end);
    // 这个函数用来将两个排好序的数组进行合并
    void merge(int *num, int start, int middle, int end);
    
    int main()
    {
        // 测试数组
        int num[10] = {12, 54, 23, 67, 86, 45, 97, 32, 14, 65};
        int i;
        // 排序之前
        printf("Before sorting:
    ");
        for (i = 0; i < 10; i++)
        {
            printf("%3d", num[i]);
        }
        printf("
    ");
        // 进行合并排序
        mergesort(num, 0, 9);
        printf("After sorting:
    ");
        // 排序之后
        for (i = 0; i < 10; i++)
        {
            printf("%3d", num[i]);
        }
        printf("
    ");
        return 0;
    }
    
    //这个函数用来将问题细分
    
    void mergesort(int *num, int start, int end)
    {
        int middle;
        if(start < end)
        {
            middle = (start + end) / 2;
            // 归并的基本思想
            // 排左边
            mergesort(num, start, middle);
            // 排右边
            mergesort(num, middle + 1, end);
            // 合并
            merge(num, start, middle, end);
        }
    }
    
    //这个函数用于将两个已排好序的子序列合并
    
    void merge(int *num, int start, int middle, int end)
    {
    
        int n1 = middle - start + 1;
        int n2 = end - middle;
        // 动态分配内存,声明两个数组容纳左右两边的数组
        int *L = new int[n1 + 1];
        int *R = new int[n2 + 1];
        int i, j = 0, k;
    
        //将新建的两个数组赋值
        for (i = 0; i < n1; i++)
        {
            *(L + i) = *(num + start + i);
        }
        // 哨兵元素
        *(L + n1) = 1000000;
        for (i = 0; i < n2; i++)
        {
            *(R + i) = *(num + middle + i + 1);
        }
        *(R + n2) = 1000000;
        i = 0;
        // 进行合并
        for (k = start; k <= end; k++)
        {
            if(L[i] <= R[j])
            {
                num[k] = L[i];
                i++;
            }
            else
            {
                num[k] = R[j];
                j++;
            }
        }
        delete [] L;
        delete [] R;
    }

    入栈操作

    #include "process.h"
    #include "stdio.h"
    #include "assert.h"
    
    const int stackIncreament = 6; //栈溢出时扩展空间的增量
    
    class SeqStack
    {
    private:
        int top;                    //栈顶指针
        int MAX;                    //栈的最大可容纳个数
        int *elements;              //存放栈中元素的栈数组
        void overflowProcess();     //栈的溢出处理
    public:
        SeqStack(int sz = 50);      //构造函数
        ~SeqStack()
        {
            delete[]elements;    //析构函数
        }
        bool pop1(int &x);          //元素出栈
        void push1(const int &x);   //新元素进栈
        bool IsEmpty1()const;       //判断栈空与否
        bool IsFull1()const;        //判断栈满与否
        void output1();              //输出元素进栈顺序
        void output(int x);          //输出x
    
    };
    
    SeqStack::SeqStack(int sz): top(-1), MAX(sz)
    {
        elements = new int[MAX];   //创建栈的数组空间
        assert(elements != NULL);  //断言:动态存储分配成功与否
    }
    
    bool SeqStack::pop1(int &x)          //栈顶元素出栈
    {
        if(IsEmpty1() == true) return false; //判栈空否,若栈空则函数返回
        x = elements[top--];           //栈顶指针退1
        return true;                   //退栈成功
    }
    
    void SeqStack::push1(const int &x)     //新元素进栈
    {
        if(IsFull1() == true)  overflowProcess(); //栈满则溢出处理
        elements[++top] = x;      //栈顶指针先加1,再进栈
    }
    
    bool SeqStack::IsEmpty1() const   //判断栈空与否
    {
        return (top == -1) ? true : false;
    }
    
    bool SeqStack::IsFull1()const    //判断栈满与否
    {
        return (top == MAX - 1) ? true : false;
    }
    
    void SeqStack::overflowProcess()  //栈的溢出处理
    {
        //私有函数,扩充栈的存储空间。
        int *Array = new int[MAX + stackIncreament];   //和课本不一样 ??????????
        if(Array == NULL)
        {
            printf("存贮分配失败 ! 
    ");
            exit(1);
        }
        for(int i = 0; i <= top; i++)   Array[i] = elements[i];
        MAX = MAX + stackIncreament;
        delete []elements;
        //elements=Array;
    }
    
    void SeqStack::output1()              //元素入栈顺序输出
    {
        int n = 0;
        int t = top;
        for(int i = 0; i < top; i++)
        {
            printf("  %d", elements[i]);
            n++;
            if(n % 10 == 0)
                printf("
    ");
        }
    }
    
    void SeqStack::output(int x)              //栈内元素输出
    {
        printf("  %d", x);
    }
    
    //----------------------顺序栈函数--------------------------//
    void SeqStack1( SeqStack  A)
    {
        int x = -1;
        int X;
        printf("请输入要入栈A的元素值,以0结束:
    ");
        while(x != 0)                  //新元素进栈
        {
            scanf("%d", &x);
            A.push1(x);
        }
        printf("
    元素进栈顺序是 :");
        A.output1();
        printf("
    
    ");
    
        A.pop1(X);            //元素出栈
        if(!A.pop1(X))
            printf("元素出栈失败 !
    ");
        else
        {
            printf("
    栈顶元素是:  ");
            A.output(X);
            printf("
    ");
            printf("
    元素出栈的结果是 : ");
            A.output(X);
            while(A.pop1(X))
                A.output(X);
        }
    }
    
    void main()
    {
        printf("----------顺序栈的调试----------
    ");
        printf("
     
    ");
        SeqStack  A;
        SeqStack1(A);
        printf("
     
    ");
    }

    数塔

    #include<iostream>
    using namespace std;
    
    
    
    void main()
    {
    
        int data[50][50];
    
        int maxvalue[50][50];
    
        int path[50][50];
    
    
        int i, j, n;
        cout << "please input the number of rows:";
        cin >> n;
        cout << "please input the date of several tower:" << endl;
        for(i = 1; i <= n; i++)
        {
            for(j = 1; j <= i; j++)
            {
    
                cin >> data[i][j];
                maxvalue[i][j] = data[i][j];
                path[i][j] = 0;
            }
        }
        for(i = n - 1; i >= 1; i--)
        {
            for(j = 1; j <= i; j++)
            {
                if(maxvalue[i + 1][j] > maxvalue[i + 1][j + 1])
                {
                    maxvalue[i][j] = maxvalue[i][j] + maxvalue[i + 1][j];
                    path[i][j] = 0;
                }
                else
                {
                    maxvalue[i][j] = maxvalue[i][j] + maxvalue[i + 1][j + 1];
                    path[i][j] = 1;
                }
            }
        }
        cout << "maxvalue=" << maxvalue[1][1] << endl;
        j = 1;
        cout << "path:";
        for(i = 1; i <= n - 1; i++)
        {
            cout << data[i][j] << "-->";
            j = j + path[i][j];
        }
        cout << data[n][j] << endl;
    }
    

    数字旋转方阵

    #include <iostream>
    using namespace std;
    
    #define N 9
    int P[N][N];
    
    void fill (int number, int begin, int size)
    {
        if (size == 0)
            return ;
        if (size == 1)
        {
            P[begin][begin] = number;
            return ;
        }
        int i = 0;
        int h = begin, v = begin;
        P[h][v] = number;
        number++;
    
        for (i = 0; i < size - 1; i++)
        {
            h++;
            P[h][v] = number;
            number++;
        }
        for (i = 0; i < size - 1; i++)
        {
            v++;
            P[h][v] = number;
            number++;
        }
        for (i = 0; i < size - 1; i++)
        {
            h--;
            P[h][v] = number;
            number++;
        }
        for (i = 0; i < size - 2; i++) //修改的地方
        {
            v--;
            P[h][v] = number;
            number++;
        }
        fill(number, v, size - 2);
    
    }
    int main ()
    {
        fill(1, 0, N);
    
        int h, v;
        for (h = 0; h < N; h++)
        {
            for (v = 0; v < N; v++)
                cout << P[h][v] << '	';
            cout << '
    ';
        }
        return 0;
    }

    选择排序

    #include<stdio.h>
    
    void main()
    {
        int i, j, min, temp;
        int a[10];
        printf("请输入十个整数:");
        for(i = 0; i <= 9; i++)
            scanf("%d", &a[i]);
        for(i = 0; i < 9; i++)
        {
            min = i;
            for(j = i + 1; j <= 9; j++)
            {
                if(a[min] > a[j])
                {
                    min = j;
                }
                temp = a[j];
                a[j] = a[min];
                a[min] = temp;
            }
        }
        for(i = 0; i <= 9; i++)
            printf("%4d", a[i]);
    }

    冒泡排序

    #include<stdio.h>
    
    void main()
    {
        int i, j, temp;
        int a[10];
        printf("请输入十个整数:");
        for(i = 0; i <= 9; i++)
            scanf("%d", &a[i]);
        for(i = 0; i < 9; i++)
            for(j = 9; j > i; j--)
            {
                if(a[j] < a[j - 1])
                {
                    temp = a[j];
                    a[j] = a[j - 1];
                    a[j - 1] = temp;
                }
            }
        /*
         for(j=0;j<9-i;j++)
         {
          if(a[j]>a[j+1])
          {
            temp=a[j];
            a[j]=a[j+1];
            a[j+1]=temp;
          }
         }大的气泡往下沉,小的气泡往上浮!!!注意:是a[j-1]还是a[j+1];
         深刻了解!!!
        */
        for(i = 9; i >= 0; i--)
            printf("%4d", a[i]);
    }

    折半查找

    #include<iostream>
    using namespace std;
    int binary_search(char *data, int len, char target)
    {
        int high = len - 1, low = 0, mid;
        mid = (high + low) / 2;
        while(high >= low)
        {
            if(target > data[mid])
                low = mid + 1;
            else if(target < data[mid])
                high = mid - 1;
            else return mid;
            mid = (high + low) / 2;
        }
        return -1;
    }
    int main()
    {
        char a[] = "abcdefghijklmn";
        char taget;
        cout << "输入要查找的字符
    ";
        cin >> taget;
        int i = binary_search(a, strlen(a), taget);
        if(i == -1)
            cout << "Not Foun!
    ";
        else
            cout << "Found  " << a[i] << " in the " << i + 1 << " position";
        return 0;
    }

    二叉搜索树

    #include <iostream>
    #define N 5
    using namespace std;
    
    
    #include <iostream>
    #include <cstring>
    using namespace std;
    
    class node
    {
    public:
        node(int i): data(i), left(NULL), right(NULL) {}
        void inorder(node *&root)      //中序遍历,符合升序输出
        {
            if(root != NULL)
            {
                inorder(root->left);
                cout << root->data << ' ';
                inorder(root->right);
            }
        }
        void insert(node *&ptr, int item) //在查找树中插入元素
        {
            if(ptr == NULL)
                ptr = new node(item);
            else if(item < ptr->data)
                insert(ptr->left, item);
            else insert(ptr->right, item);
        }
        node *find(node *&ptr, int item) //在查找树中查找元素,找到返回所在结点指针,找不到返回空指针。
        {
            if(ptr == NULL)
                return NULL;
            if(ptr->data == item)
                return ptr;
            else if(item < ptr->data)
                find(ptr->left, item);
            else find(ptr->right, item);
        }
        node *&findy(node *&ptr, int item) //在查找树中查找肯定存在的元素,并返回其引用
        {
            if(ptr->data == item)
                return ptr;
            else if(item < ptr->data)
                findy(ptr->left, item);
            else findy(ptr->right, item);
        }
        void printfind(node *&ptr, int item) //在查找树中查找元素,并输出经过路径
        {
            if(ptr->data == item)
            {
                cout << item << endl;
                return;
            }
            else if(item < ptr->data)
            {
                cout << ptr->data << ' ' << endl;
                printfind(ptr->left, item);
            }
            else
            {
                cout << ptr->data << ' ' << endl;
                printfind(ptr->right, item);
            }
        }
        node *rl()
        {
            return left;
        }
        node *rr()
        {
            return right;
        }
        void dele(node *&ptr)       //删除值为item所在结点
        {
            if(ptr->rl() == NULL && ptr->rr() == NULL)
                ptr = NULL;
            else if(ptr->rr() == NULL)
                ptr = ptr->rl();
            else if(ptr->rl() == NULL)
                ptr = ptr->rr();
            else
            {
                node *temp = ptr->rl();
                ptr = ptr->rr();
                node *temp2 = ptr;
                while(temp2->rl() != NULL)
                    temp2 = temp2->rl();
                temp2->setl(temp);
            }
        }
        void setl(node *l)
        {
            left = l;
        }
    private:
        int data;
        node *left;               //左孩子结点
        node *right;              //右孩子结点
    };
    
    int main()
    {
        char a[10];
        int t, i = 0, j;
        cout << "输入数字个数:";
        cin >> t;
        cout << "输入" << t << "个数字,数字之间用空格隔开:";
        cin >> j;
        node *x = new node(j);
        for(; i < t - 1; i++)
        {
            cin >> j;
            x->insert(x, j);
        }
        cout << "输入操作(当输入串为(0 0)时结束程序):" << endl;
        cin >> a >> j;
        while(strcmp(a, "0") != 0)
        {
            if(strcmp(a, "S") == 0)
            {
                if(x->find(x, j) == NULL)
                    cout << "-1" << endl;
                else
                    x->printfind(x, j);
            }
            else if(strcmp(a, "D") == 0)
            {
                node *t = x->find(x, j);       //定位结点
                if(t != NULL)
                {
                    node *&y = x->findy(x, j);
                    x->dele(y);
                }
                x->inorder(x);
            }
            cout << "
    输入操作(当输入串为0时结束程序):" << endl;
            cin >> a >> j;
        }
        return 0;
    }
  • 相关阅读:
    算法提高 身份证号码升级
    枚举排列
    排列数
    算法训练 K好数
    算法训练 前缀表达式
    算法训练 区间k大数查询
    最大最小公倍数
    Anagrams问题
    Uiautomator 2.0
    Uiautomator 2.0
  • 原文地址:https://www.cnblogs.com/ainima/p/6331880.html
Copyright © 2020-2023  润新知