数据结构基础知识

1.n的阶乘
2.河内塔
3.不排序,求无序数组中第k大的数
4.递增链表的插入
5.求集合数据的均方差
6.数列求和
7.装箱问题
8.数组元素循环右移问题
9.两个有序链表序列的合并
10.连个有序链表的交集
11.两个有序序列的中位数

#include <stdio.h>
#include <stdlib.h>
#include <math.h>


void swap(int *a , int *b);
int count = 0;
int i = 0;

//1.n的阶乘
void testFactorial();
//2.河内塔
void testHanoi();
//3.不排序,求无序数组中第k大的数
void testFindKLargest();
//4.递增链表的插入
void testInsertNode();
//5.求集合数据的均方差
void testSumOfSquares();
//6.数列求和
void testSumOfSequence();
//7.装箱问题
void testpackboxes();
//8.数组元素循环右移问题
void testShiftRight();
//9.两个有序链表序列的合并
void testMergeLinkList();
//10.连个有序链表的交集
void testIntersectionLinkList();
//11.两个有序序列的中位数
void testCenterLinkList();
int main(int argc, const char * argv[]) {
//    testFactorial();
//    testHanoi();
//    testFindKLargest();
//    testInsertNode();
//    testSumOfSquares();
//    testSumOfSequence();
//    testpackboxes();
//    testMergeLinkList();
//    testIntersectionLinkList();
    testCenterLinkList();
    return 0;
}
//1.阶乘问题
long int factorial(int n){
    if (n == 0) {
        return 1;
    }else{
        return n * factorial(n - 1);
    }
}
/*
 2.河内塔(汉诺塔)问题求解
 汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。
 大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照
 大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小
 顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在
 三根柱子之间一次只能移动一个圆盘。
 */
void testFactorial(){
    printf("输入一个整数求其阶乘:\n");
    int n;
    scanf("%d",&n);
    long int a = factorial(n);
    printf("%ld\n",a);
}
//将编号为n的盘子由from移动到to
void mobile(int n,char from,char to){
    printf("第%d步:将%d号盘子%c---->%c\n",i++,n,from,to);
}
/**
 @param n 要移动盘子的个数
 @param from 起始塔
 @param denpend_on 借助塔
 @param to 目的塔
 */
void hanoi(int n , char from , char denpend_on, char to){
    //把一个盘子从起始塔移动到目标塔
    if (n == 1) {
        mobile(1, from, to);
    }else{
        //把n-1个盘子从起始塔借助目的塔移动到借助塔上,这样起始塔上就剩下一个最大盘子
        hanoi(n-1, from, to, denpend_on);
        /*
         把剩下的第n个盘子移动到目的塔上,
         这样起始塔上就没有盘子了,当做借助塔用,
         借助塔上有n-1个盘子,成为起始塔
         */
        mobile(n, from, to);
        //把n-1个盘子从借助塔 借助 起始塔 移动到 目的塔 上
        hanoi(n-1, denpend_on, from, to);
    }
}
void testHanoi(){
    printf("请输入盘子的个数:\n");
    int n;
    scanf("%d",&n);
    char x='A',y='B',z='C';
    printf("盘子移动情况如下:\n");
    hanoi(n,x,y,z);
}



/**
 3.不排序,求一个数组中的K大的数

 @param a 数组
 @param K 第K大
 @param Left 左边个数
 @param Right 右边个数
 @return 返回的结果
 */
int findKLargest(int a[] ,int K , int Left , int Right){
    int e = a[Left];
    int L = Left , R = Right;
    while (1) {
        while (Left <= Right && e <= a[Left]) {
            Left++;
        }
        while (Left < Right && e > a[Right]) {
            Right--;
        }
        if (Left < Right) {
            printf("Left:%d -- Right:%d\n",Left,Right);
            swap(&a[Left], &a[Right]);
        }else{
            break;
        }
    }
    swap(&a[Left - 1], &a[L]);
    if (Left - L - 1 >= K) {
        return findKLargest(a, K, L, Left - 2);
    }else if (Left - L - 1 < K - 1){
        return findKLargest(a, K - Left + L, Left, R);
    }else{
        return e;
    }
}
void testFindKLargest(){
    printf("输入长度:\n");
    int n;
    scanf("%d",&n);
    int a[n];
    printf("一次输入%d个数\n",n);
    for (int i = 0; i < n; i++) {
        scanf("%d",&a[i]);
    }
    printf("\n");
    printf("查找第K大 K:\n");
    int K;
    scanf("%d",&K);
    int e = findKLargest(a, K, 0, n - 1);
    printf("\n%d\n",e);
}



/**
 4.递增链表的插入
 */
struct node {
    int value;
    struct node *next;
};
void logLinkList(struct node *head){
    struct node *p = head;
    while (p != NULL) {
        printf("%d   ",p->value);

        p = p->next;
    }
    printf("\n");
}
struct node *insertNode(struct node *head,int k){
    struct node *newNode = malloc(sizeof(struct node));
    newNode->value = k;

    //方法一:在开头先插入一个节点
    struct node *tmpHead = malloc(sizeof(struct node));
    tmpHead->next = head;
    struct node *p = tmpHead;
    while (p->next != NULL && p->next->value < k) {
        p = p->next;
    }
    newNode->next = p->next;
    p->next = newNode;
    if (p == tmpHead) {
        head = newNode;
    }else{
        free(tmpHead);
        tmpHead = NULL;
    }
    return head;
    //    struct node *p = head;
    //    if (head == NULL) {
    //        return newNode;
    //    }
    //    if (head->value > k) {
    //        newNode->next = head;
    //        return newNode;
    //    }
    //    while (p->next != NULL && p->next->value < k) {
    //        p = p->next;
    //    }
    //    newNode->next = p->next;
    //    p->next = newNode;
    //    return head;
}

struct node *createLinkList(){
    struct node *head = NULL;
    struct node *newNode = NULL;
    struct node *oldNode = NULL;
    printf("输入长度:\n");
    int n;
    scanf("%d",&n);
    if (n == 0) {
        return head;
    }
    newNode = malloc(sizeof(struct node));
    printf("一次输入%d个数\n",n);
    for (int i = 0; i<n; i++) {
        if (head == NULL) {
            head = newNode;
        }else{
            oldNode->next = newNode;
        }
        oldNode = newNode;
        scanf("%d",&oldNode->value);

        newNode = malloc(sizeof(struct node));
    }
    free(newNode);
    newNode = NULL;
    oldNode->next = NULL;
    return head;
}
void testInsertNode(){
    struct node *head = createLinkList();
    logLinkList(head);
    int k = -1;
    while (k != 0) {
        printf("输入要插入的数 K:\n");
        scanf("%d",&k);
        head = insertNode(head, k);
        logLinkList(head);
    }
}



/*
 5.求集合数据的均方差
 */
double avg(int a[] , int n){
    if (n == 0) {
        return 0;
    }
    double sum = 0;
    for (int i = 0; i < n; i++) {
        sum += a[i];
    }
    return sum/(double)n;
}
double sumOfSquares(int a[] , int n){
    double Avg = avg(a, n);
    printf("%f\n",Avg);
    double sum = 0;
    for (int i = 0 ; i < n; i++) {
        sum += (a[i] - Avg) * (a[i] - Avg);
    }
    printf("%f\n",sum);
    printf("%f\n",sum/(double)n);
    return sqrt(sum/(double)n);
}
void testSumOfSquares(){
    printf("输入长度:\n");
    int n;
    scanf("%d",&n);
    int a[n];
    printf("一次输入%d个数\n",n);
    for (int i = 0; i < n; i++) {
        scanf("%d",&a[i]);
    }
    //    int a[10] = {6,3,7,1,4,8,2,9,11,5}; 3.03974

    double res = sumOfSquares(a, n);
    printf("\n%.5f\n",res);
}

/*
 6.给定某整数A(1≤A≤9)以及非负整数N(0≤N≤100 000),
 求数列之和
 S = A + AA + AAA + ...+ AA...A(N个A)。
 例如:
 S = 1 + 11 + 111 = 123
 */
int *sumOfTwoArray(int array1[] , int array2[] , int n){
    printf("array1:\n");
    for (int i = n - 1; i >= 0; i--) {
        printf("%d  ",array1[i]);
    }
    printf("\narray2:\n");
    for (int i = n - 1; i >= 0; i-- ){
        printf("%d  ",array2[i]);
    }

    int *res = (int *)malloc(n-1);
    int y = 0;
    for (int i = 0 ; i < n; i++) {
        int e = array1[i] + array2[i] + y;
        printf("\n i : %d array1 %d  array2 %d y : %d  e :%d", i ,array1[i], array2[i],y , e);
        //        if (i == n - 1) {
        //            res[i] = array1[i] + array2[i] + y;
        //        }else{
        //            res[i] = e%10;
        //        }
        res[i] = e%10;
        y = e/10;
    }
    printf("\nres:\n");

    for (int i = n - 1; i >= 0; i-- ){
        printf("%d  ",res[i]);
    }
    printf("\n");
    printf("\n");

    return res;
}
//double pow(double x,double y);
void sumOfSequence(int A , int B){

    //    int sum = 0;
    //    int a = A;
    //    for (int i = 0; i < B; i++) {
    //        int N = A * (B-i) * pow(10, i);
    //        sum += N;
    //    }
    //    printf("\n%d\n",sum);
    //    sum = 0;
    //    int tN = 0;
    //    for (int i = 1; i <= B; i++) {
    //        tN += A;
    //        sum += tN;
    //        A = A * 10;
    //    }
    //    printf("\n%d\n",sum);
    //    A = a;
    int a[B];
    int *c = malloc(B - 1);
    for (int i = B - 1; i >= 0; i--) {
        c[i] = 0;
        a[i] = 0;
    }
    for (int i = 0; i < B; i++) {
        for (int j = 0; j <= i; j ++) {
            a[j] = A;
        }
        for (int i = B - 1; i >= 0; i--) {
            printf("%d",a[i]);
        }
        printf("\nc:\n");
        for (int i = B - 1; i >= 0; i--) {
            printf("%d",c[i]);
        }
        printf("\n");
        c = sumOfTwoArray(a, c, B);
    }
    printf("\n");
    for (int i = B - 1; i >= 0; i--) {
        printf("%d",c[i]);
    }
    printf("\n");


}
void testSumOfSequence(){
    printf("输入A和B的值:\n");
    int A , B;
    scanf("%d %d",&A , &B);
    sumOfSequence(A, B);
}

/*
 7.假设有N(≤1000)项物品,大小分别为s1,s2,s3...si...Sn si是1到100的整数
 要把这些物品存放到容量为100的一批箱子中(序号1—N).
 装箱方法:对每项物品,书序扫描箱子,把该物品放入足以能够容下它的的
 第一个箱子中。请写一个程序模拟这种装箱过程,并输出每个物品所在的箱子
 的序号,以及放置全部物品所需的箱子数目。
 */
void packboxes(int array[][2] , int N){
    int box[1000] = {0};
    int count = 1;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            if (array[i][0] + box[j] <= 100) {
                array[i][1] = j + 1;
                box[j] = box[j] + array[i][0];
                if (j + 1 > count) {
                    count = j + 1;
                }
                break;
            }
        }
    }
    for (int i = 0; i < N; i++) {
        printf("%3d %d\n",array[i][0],array[i][1]);
    }
    printf("\ncount:%d\n",count);
}
void testpackboxes(){
    printf("输入长度:\n");
    int n;
    scanf("%d",&n);
    int a[n][2];
    printf("一次输入%d个数\n",n);
    int sum = 0;
    for (int i = 0; i < n; i++) {
        //        scanf("%d",&a[i][0]);
        a[i][0] = (rand() % 100) + 1;
        sum += a[i][0];
        a[i][1] = 0;
    }
    printf("\nsum:%d\n",sum);
    printf("\n");
    packboxes(a, n);
}


/*
 8.数组元素循环右移问题
 */
void shiftOne(int array[] , int n){
    int tmp = array[n-1];
    for (int i = n - 1; i > 0; i--) {
        array[i] = array[i-1];
        ++count;
    }
    array[0] = tmp;
}
void shiftRight(int array[], int n, int m){
    int j = m % n;
    for (int i = 0; i < j; i++) {
        shiftOne(array, n);
    }
}

void swap(int *a , int *b){
//第一种算法
//    int c = *a;
//    *a = *b;
//    *b = c;
//第二种算法
//    *a = *a^*b;
//    *b = *a^*b;//把第一次的结果带进去,就是(*a^*b)^*b,对同一个数异或运算等于自身;
//    *a = *a^*b;//把第一次的结果带进去,就是(*a^*b)^*b,此时*b = *a,(*a^*b)^*a
//第三种算法
    int c = *a - *b;
    *a = *a - c;
    *b = *b + c;
}
void shiftRight_2(int array[] , int n, int m){
    for (int i = 0 , j = n-1; i < j;i++,j--) {
        swap(&array[i], &array[j]);
        ++count;
    }
    m = m % n;
    for (int i = 0 , j = m - 1; i < j; i++ , j--) {
        swap(&array[i], &array[j]);
        ++count;
    }
    for (int i = m , j = n - 1; i < j; i++ , j--) {
        swap(&array[i], &array[j]);
        ++count;
    }
}
void shiftRight_3(int array[] , int n, int m){
    m = m%n;
//    for (int i = 0, j = m;j < n - m; i++ , j++) {
//        swap(&array[i], &array[j]);
//    }
}
void testShiftRight(){
    int a[6] = {1,2,3,4,5,6};
    shiftRight_2(a, 6, 8);
    for (int i; i < 6; i++) {
        printf("%d\n",a[i]);
    }
    printf("n=%d\n",count);

}
/*
 9.已知两个非降序链表S1与S2,设计函数构造出S1与S2的并集新非降序链表S3.
 */
struct node *mergeLinkList(struct node *head1, struct node *head2){
    if (head1 == NULL) {
        return head2;
    }
    if (head2 == NULL) {
        return head1;
    }
    struct node *p = head1;
    while (p != NULL) {
        head2 = insertNode(head2, p->value);
        p = p->next;
    }
    return head2;
}
void testMergeLinkList(){
    printf("创建第一个非降序链表\n");
    struct node *head1 = createLinkList();
    printf("创建第二个非降序链表\n");
    struct node *head2 = createLinkList();
    struct node *mLink = mergeLinkList(head1, head2);
    logLinkList(mLink);
}
/*
 10.已知两个非降序链表序列S1与S2,设计函数构造出S1与S2的交集新链表S3.
 */
int hasEqualNode(struct node *head, int k){
    struct node *p = head;
    while (p != NULL) {
        if (p->value == k) {
            return 1;
        }else{
            p = p->next;
        }
    }
    return 0;
}
struct node *IntersectionLinkList(struct node *head1, struct node *head2){
    if (head2 == NULL || head1 == NULL) {
        return NULL;
    }
    struct node *p = head1;
    struct node *newNode = NULL;
    while (p != NULL) {
        if (hasEqualNode(head2, p->value)) {
            newNode = insertNode(newNode, p->value);
        }
        p = p->next;
    }
    return newNode;
}
void testIntersectionLinkList(){
    printf("创建第一个非降序链表\n");
    struct node *head1 = createLinkList();
    printf("创建第二个非降序链表\n");
    struct node *head2 = createLinkList();
    struct node *mLink = IntersectionLinkList(head1, head2);
    logLinkList(mLink);
}
/*
 11.已知有两个等长的非降序序列,设计函数S1与S2并集的中位数
 */
struct node *bingjiLinkList(struct node *head1, struct node *head2){

    struct node *p = head1;
    while (p != NULL) {
        if (hasEqualNode(head2, p->value) == 0) {
            head2 = insertNode(head2, p->value);
        }
        p = p->next;
    }
    return head2;
}
void testCenterLinkList(){
    printf("创建第一个非降序链表\n");
    struct node *head1 = createLinkList();
    printf("创建第二个非降序链表\n");
    struct node *head2 = createLinkList();
    struct node *mLink = bingjiLinkList(head1, head2);
    logLinkList(mLink);
    struct node *p = mLink;
    int count = 0;
    while (p != NULL) {
        p = p->next;
        count++;
    }
    int i = 0;
    int c = (count%2 == 0) ? (count/2 - 1) : count/2;
    p = mLink;

    while (i < c) {
        p = p->next;
        i++;
    }
    printf("中位数:%d\n", p->value);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值