C语言数据结构-2020级ICODING答案分享

详细学习版本请看https://blog.csdn.net/aiqq136/article/details/114590856

目录

顺序表 删除指定范围

顺序表 删除重复

顺序表 数据调整

链表 删除范围内结点

链表 倒数查找

链表 合并

队列 循环链表表示队列

栈 后缀表达式计算

串-串比较

串-串替换

串-块链串

矩阵加法

十字链表

树与二叉树--先序遍历

树与二叉树--路径

树与二叉树--共同祖先

树与二叉树--树转二叉树


顺序表 删除指定范围

#include "list.h" // 请不要删除,否则检查不通过
#include 
#include 

void del_x2y(SeqList* L, ElemType x, ElemType y)
{
    int i = 0, j = 0;
    for (i = 0; i <= L->last; i++) {
        if (L->elem[i] < x || L->elem[i] > y) {
            L->elem[j++] = L->elem[i]; //在范围外,则继续赋值
        }
    }
    L->last = j - 1; //储存下标位置
}

顺序表 删除重复

 

 

#include "list.h" // 请不要删除,否则检查不通过
#include 
#include 

void del_dupnum(SeqList* L)
{
    int min = L->elem[0];
    int tmp = L->elem[0];
    for (int i = 1; i <= L->last; i++) {
        if (L->elem[i] == tmp)
            L->elem[i] = min;
        else
            tmp = L->elem[i];
    }
    int p = 1, q = 1;
    while (q <= L->last) {
        if (L->elem[q] != min) {
            L->elem[p] = L->elem[q];
            p++;
        }
        q++;
    }
    L->last = p - 1;
}

顺序表 数据调整

#include "list.h" // 请不要删除,否则检查不通过
#include 
#include 

//要求左奇数右偶数
void odd_even(SeqList* L)
{
    int* left = &(L->elem[0]);
    int* right = &(L->elem[L->last]);
    int tmp;
    while (left < right) {
        //左边是偶数
        if (*left % 2 == 0) {
            //右边是奇数
            if (*right % 2 == 1) {
                //交换
                tmp = *left;
                *left = *right;
                *right = tmp;
                left++;
                right--;
            } else {
                right--;
            }
        } else {
            //左边是奇数
            left++;
        }
    }
}

链表 删除范围内结点

#include "list.h" // 请不要删除,否则检查不通过
#include 
#include 

void lnk_del_x2y(LinkList L, ElemType mink, ElemType maxk)
{
    LinkList left = NULL;
    LinkList right = NULL;
    LinkList tmp = NULL;
    //找到左指针
    while (L->next != NULL) {
        if ((L->next->data > mink) && (L->next->data < maxk)) {
            left = L;
            L = L->next;
            break;
        } else {
            L = L->next;
        }
    }
    //找到右指针
    while (L->next != NULL) {
        if ((L->data > mink) && (L->data < maxk)) {
            tmp = L;
            L = L->next;
            free(tmp);
        } else {
            right = L;
            break;
        }
    }
    if (right == NULL)
        return;
    left->next = right;
}

链表 倒数查找

#include "list.h" // 请不要删除,否则检查不通过
#include 
#include 

int lnk_search(LinkList L, int k, ElemType* p_ele)
{
    //带计数器遍历链表,得到链表长度
    int count = 1;
    LinkList tmp = L;
    int i = 0;
    while (tmp->next != NULL) {
        tmp = tmp->next;
        count++;
    }
    tmp = L;
    //遍历count-k次链表
    if (k > count || k <= 0) {
        return 0;
    } else {
        for (i = 0; i < count - k; i++) {
            tmp = tmp->next;
        }
        *p_ele = tmp->data;
        return 1;
    }
}

链表 合并

#include "list.h" // 请不要删除,否则检查不通过
#include 
#include 

void lnk_merge(LinkList A, LinkList B, LinkList C)
{
    LinkList tmp = C; //记录最末尾的位置
    LinkList tmpA = A->next;
    LinkList tmpB = B->next;

    while (1) {
        if (tmpA == NULL) {
            return C;
        } else {
            tmp->next = tmpA;
            tmp = tmp->next;
            tmpA = tmpA->next;
        }

        if (tmpB == NULL) {
            return C;
        } else {
            tmp->next = tmpB;
            tmp = tmp->next;
            tmpB = tmpB->next;
        }
    }
}

队列 循环链表表示队列

#include "list.h" // 请不要删除,否则检查不通过
#include 
#include 

bool init_queue(LinkQueue* LQ) //二重指针
{
    *LQ = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
    if (*LQ == NULL)
        return false;
    (*LQ)->next = (*LQ);
    return true;
}

bool enter_queue(LinkQueue* LQ, ElemType x)
{
    LinkQueue p = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
    if (p == NULL)
        return false;
    p->data = x;
    p->next = (*LQ)->next;
    (*LQ)->next = p;
    (*LQ) = p;
    return true;
}

bool leave_queue(LinkQueue* LQ, ElemType* x)
{
    if ((*LQ)->next == (*LQ))
        return false;
    LinkQueue p = (*LQ)->next->next;
    *x = p->data;
    if ((*LQ)->next->next != (*LQ)) //多个节点
    {
        (*LQ)->next->next = (*LQ)->next->next->next;
    } else //两个节点
    {
        (*LQ) = (*LQ)->next;
        (*LQ)->next = (*LQ);
    }
    free(p);
    return true;
}

栈 后缀表达式计算

#include "list.h" // 请不要删除,否则检查不通过
#include 
#include 

int compute_reverse_polish_notation(char* str)
{
    int i = 0;
    Stack S;
    init_stack(&S);
    ElemType number_to_push, num1, num2;
    while (str[i] != '\0') {
        if (str[i] != ' ') {
            if (str[i] >= '0' && str[i] <= '9') {
                number_to_push = 0;
                while (str[i] != ' ' && str[i]) {
                    number_to_push = number_to_push * 10 + (str[i] - '0');
                    i++;
                }
                push(&S, number_to_push);
            } else {
                pop(&S, &num2);
                pop(&S, &num1);
                switch (str[i]) {
                case '+': {
                    num1 += num2;
                    break;
                }
                case '-': {
                    num1 -= num2;
                    break;
                }
                case '*': {
                    num1 *= num2;
                    break;
                }
                case '/': {
                    num1 /= num2;
                    break;
                }
                case '%': {
                    num1 %= num2;
                    break;
                }
                }
                push(&S, num1);
            }
        }
        i++;
    }
    pop(&S, &num1);
    return num1;
}

串-串比较

#include "dsstring.h" //请不要删除,否则检查不通过
#include 
#include 
//#include
int str_compare(const char* ptr1, const char* ptr2)
{
    //assert(ptr1 && ptr2); //防止传进来为空指针
    //ASCII中A为65,a为97,差32
    while (*ptr1 == *ptr2 || ((*ptr1) + 32 == *ptr2) || ((*ptr2) + 32 == *ptr1)) {
        if (*ptr1 == '\0') {
            return 0;
        }
        ptr1++;
        ptr2++;
    }
    return (*ptr1 - *ptr2);
}

串-串替换

 

#include "dsstring.h"
#include 
#include 

void* Memset(void* s, int c, size_t n)
{
    if (NULL == s || n < 0)
        return NULL;
    char* tmpS = (char*)s;
    while (n-- > 0)
        *tmpS++ = c;
    return s;
}

char* Strncat(char* dest, const char* source, int num)
{
    //assert(dest != NULL);
    //assert(source != NULL);
    char* ret = dest;

    while (*dest != '\0') {
        dest++;
    }
    while (num && (*dest++ = *source++)) {
        num--;
    }
    return ret;
}

char* Strcat(char* dest, const char* src)
{
    //assert(dest != NULL);
    //assert(src != NULL);
    char* ret = dest;
    //1.找到目的字符串的'\0'
    while (*dest != '\0') {
        dest++;
    }
    //2.追加
    while (*dest++ = *src++) {
        ;
    }
    return ret;
}

int Strlen(char* str)
{
    int count = 0;
    while (*str != '\0') {
        str++;
        count++;
    }
    return count;
}

int Strncmp(const char* str1, const char* str2, int size)
{
    for (int i = 0; i < size; ++i) {
        if (*(str1 + i) > *(str2 + i)) {
            return 1;
        } else if (*(str1 + i) < *(str2 + i)) {
            return -1;
        }
        if (*(str1 + i) == 0 || *(str2 + i) == 0) {
            break;
        }
    }
    return 0;
}

int str_replace(const char* in, char* out, int outlen, const char* oldstr, const char* newstr)
{
    //assert(in && out  && oldstr && newstr && outlen);
    Memset(out, 0, outlen);
    int count = 0;
    for (int i = 0; i < Strlen(in); i++) {
        if (!Strncmp(in + i, oldstr, Strlen(oldstr)) && (Strlen(out) + Strlen(newstr) < outlen)) {
            //查找到目标字符串
            Strcat(out, newstr);
            //把新字符串贴到缓冲字符串里
            i += Strlen(oldstr) - 1;
            count++;
        } else { //如果没有找到
            Strncat(out, in + i, 1); //将该字符写入缓冲字符串数组
        }
        if (Strlen(out) + 1 >= outlen)
            break;
    }
    return count;
}

串-块链串

#include "dsstring.h" // 请不要删除,否则检查不通过
#include 
#include 
#include 
#include 

BLString* blstr_myinit(BLString* str, int length)
{
    if (str == NULL) {
        str = (BLString*)malloc(sizeof(BLString));
        // assert(str);
    }
    blstr_init(str);
    // 分配空间
    str->len = length;
    if (length == 0)
        return str;
    int blk = length / BLOCK_SIZE;
    int offset = length % BLOCK_SIZE;
    str->head = (Block*)malloc(sizeof(Block));
    memset(str->head->ch, BLS_BLANK, sizeof(char) * BLOCK_SIZE);
    str->head->next = NULL;
    str->tail = str->head;
    Block* cnt = str->head;
    for (int i = 0; i < blk; i++) {
        if (i == blk - 1 && offset == 0)
            break;
        Block* p = (Block*)malloc(sizeof(Block));
        memset(p->ch, BLS_BLANK, sizeof(char) * BLOCK_SIZE);
        p->next = NULL;
        cnt->next = p;
        cnt = cnt->next;
    }
    str->tail = cnt;
    return str;
}
bool blstr_substr(BLString src, int pos, int len, BLString* sub)
{
    if (len == 0)
        return false;
    if (pos > src.len)
        return false;
    if (len + pos > src.len)
        len = src.len - pos;
    blstr_myinit(sub, len);
    Block *cnt = src.head, *cnt1 = sub->head;
    int offset = pos % BLOCK_SIZE, offset1 = 0;
    for (int i = 0; i < pos / BLOCK_SIZE; i++)
        cnt = cnt->next;
    while (len-- && cnt->ch[offset] != BLS_BLANK) {
        cnt1->ch[offset1++] = cnt->ch[offset++];
        if (offset == BLOCK_SIZE) {
            offset = 0;
            cnt = cnt->next;
        }
        if (offset1 == BLOCK_SIZE) {
            offset1 = 0;
            cnt1 = cnt1->next;
        }
    }
    return true;
}

矩阵加法

#include "tsmatrix.h"
#include 
#include 

bool add_matrix(const TSMatrix* pM, const TSMatrix* pN, TSMatrix* pQ)
{

    int i_M, j_M, i_N, j_N, M, N, Q;

    pQ->m = pM->m;
    pQ->n = pM->n;

    if (pM->m != pN->m || pM->n != pN->n) {
        return false;
    }

    //同时遍历两个三元组,当pM或者pN中其一元素取完循环终止
    for (M = 0, N = 0, Q = 0; M < pM->len && N < pN->len;) {

        i_M = pM->data[M].i; //M矩阵元素的行号
        i_N = pN->data[N].i; //N矩阵元素的行号
        j_M = pM->data[M].j; //M矩阵元素的列号
        j_N = pN->data[N].j; //N矩阵元素的列号

        //因为三元组是按行和列排好序的所以比较行数先判断是否来自同一行
        if (i_M > i_N) //N的行号小于M直接将N中元素加入Q矩阵
        {
            //复制N到Q
            pQ->data[Q].i = pN->data[N].i;
            pQ->data[Q].j = pN->data[N].j;
            pQ->data[Q].e = pN->data[N].e;
            N++; //N矩阵地址加一表示向后取一个元素
            Q++; //Q矩阵地址加一表示下一元素存放的地址
        } else if (i_M < i_N) //B的行号大于A直接将A中元素加入C矩阵
        {
            //复制M到Q
            pQ->data[Q].i = pM->data[M].i;
            pQ->data[Q].j = pM->data[M].j;
            pQ->data[Q].e = pM->data[M].e;
            M++; //M矩阵地址加一表示向后取一个元素
            Q++; //Q矩阵地址加一表示下一元素存放的地址
        } else //行号相同时
        {
            //在判断列好号是否来自同一行
            if (j_M > j_N) //B的列号小于A直接将B中元素加入C矩阵
            {
                //复制N到Q
                pQ->data[Q].i = pN->data[N].i;
                pQ->data[Q].j = pN->data[N].j;
                pQ->data[Q].e = pN->data[N].e;
                N++; //N矩阵地址加一表示向后取一个元素
                Q++; //Q矩阵地址加一表示下一元素存放的地址
            } else if (j_M < j_N) //B的列号小于A直接将B中元素加入C矩
            {
                //复制M到Q
                pQ->data[Q].i = pM->data[M].i;
                pQ->data[Q].j = pM->data[M].j;
                pQ->data[Q].e = pM->data[M].e;
                M++; //M矩阵地址加一表示向后取一个元素
                Q++; //Q矩阵地址加一表示下一元素存放的地址
            } else //相等
            {
                //判断元素相加是否为零
                if ((pM->data[M].e + pN->data[N].e)) //相加不为零
                {
                    pQ->data[Q].i = pM->data[M].i;
                    pQ->data[Q].j = pM->data[M].j;
                    pQ->data[Q].e = pM->data[M].e + pN->data[N].e;
                    Q++;
                }
                //无论相加是否为零都执行
                M++;
                N++;
            }
        }
    }

    while (M < pM->len) //N取完M未取完
    {
        //将M中所剩元素依次加入到Q中
        pQ->data[Q].i = pM->data[M].i;
        pQ->data[Q].j = pM->data[M].j;
        pQ->data[Q].e = pM->data[M].e;
        M++;
        Q++;
    }

    while (N < pN->len) //M取完N未取完
    {
        //复制N到Q
        pQ->data[Q].i = pN->data[N].i;
        pQ->data[Q].j = pN->data[N].j;
        pQ->data[Q].e = pN->data[N].e;
        N++;
        Q++;
    }
    pQ->len = Q;
    return true;
}

十字链表

#include "crosslist.h"
#include 
#include 

int init_cross_list(PCrossList L, const ElemType* A, int m, int n)
{
    int i, j, sum = 0;
    OLNode *p, *q;
    L->rows = m;
    L->cols = n;
    if (!(L->rowhead = (OLink*)malloc((m + 1) * (sizeof(OLink)))))
        return 0;
    if (!(L->colhead = (OLink*)malloc((n + 1) * (sizeof(OLink)))))
        return 0;
    for (i = 0; i < m; i++) {
        L->rowhead[i] = NULL;
    }
    for (i = 0; i < n; i++) {
        L->colhead[i] = NULL;
    }
    for (i = 0; i < m; i++) {
        for (j = 0; j < n; j++) {
            if (A[i * n + j] != 0) {
                sum++;
                if (!(p = (OLNode*)malloc(sizeof(OLNode))))
                    return 0;
                p->row = i;
                p->col = j;
                p->value = A[i * n + j];
                if (L->rowhead[i] == NULL || L->rowhead[i]->col > j) {
                    p->right = L->rowhead[i];
                    L->rowhead[i] = p;
                } else {
                    for (q = L->rowhead[i]; (q->right) && (q->right->col < j); q = q->right)
                        ;
                    p->right = q->right;
                    q->right = p;
                }
                if (L->colhead[j] == NULL || L->colhead[j]->row > i) {
                    p->down = L->colhead[j];
                    L->colhead[j] = p;
                } else {
                    for (q = L->colhead[j]; (q->down) && (q->down->row < i); q = q->down)
                        ;
                    p->down = q->down;
                    q->down = p;
                }
            }
        }
    }
    L->nums = sum;
    return sum;
}
void delete_crossList(PCrossList clist, int row, int col, int k)
{
    OLNode* tmp = NULL;
    OLNode* tmp1 = NULL;
    OLNode* tmp2 = NULL;

    OLNode* t = NULL;
    OLNode* t1 = NULL;
    OLNode* t2 = NULL;

    //删除一个结点需要修改行结点指针和列结点指针
    tmp = clist->rowhead[row];
    t = clist->colhead[col];
    if (tmp->value == k) {
        clist->rowhead[row] = tmp->right;
    }
    if (t->value == k) {
        clist->colhead[col] = t->down;
    }
    if (t->value == k) {
        free(t);
        return;
    }
    //行遍历元素
    while (tmp) {
        tmp1 = tmp;
        tmp = tmp->right;
        if (tmp && tmp->row == row && tmp->col == col) {
            tmp2 = tmp;
            tmp1->right = tmp2->right;
            break;
        }
    }
    //列遍历元素
    while (t) {
        t1 = t;
        t = t->down;
        if (t && t->row == row && t->col == col) {
            t2 = t;
            t1->down = t2->down;
            break;
        }
    }
    free(t);
    clist->nums--;
}
int del_cross_list(PCrossList L, ElemType k)
{
    OLink pt;
    int i, j;
    int sum = 0;
    for (i = 0; i < L->rows; i++) {
        pt = L->rowhead[i];
        for (j = 0; j < L->cols; j++) {
            if (pt && pt->col == j) {
                if (pt->value == k) {
                    delete_crossList(L, i, j, k);
                    sum++;
                }
                pt = pt->right;
            }
        }
        printf("\n");
    }
    return sum;
}

树与二叉树--先序遍历

#include "bitree.h" //请不要删除,否则检查不通过
#include 
#include 

void pre_order(BiTree root)
{
    Stack S[Stack_Size];
    BiTree T = root;
    init_stack(S);
    while (T || !is_empty(S)) {
        while (T) {
            visit_node(T);
            push(S, T);
            T = T->left;
        }
        pop(S, &T);
        T = T->right;
    }
}

树与二叉树--路径

#include "bitree.h" //请不要删除,否则检查不通过
#include 
#include 

bool path(BiTNode* root, BiTNode* node, Stack* s)
{
    BiTree T = root, p = NULL;
    if (T == NULL || node == NULL || !is_empty(s))
        return false;
    while (T || !is_empty(s)) {
        while (T) {
            push(s, T);
            if (T == node)
                return true;
            T = T->left;
        }
        top(s, &T);
        if (!T->right || T->right == p) {
            p = T;
            pop(s, &T);
            T = NULL;
        } else {
            T = T->right;
        }
    }
    return false;
}

树与二叉树--共同祖先

#include "bitree.h" //请不要删除,否则检查不通过
#include 
#include 

BiTNode* nearest_ancestor(BiTree root, BiTNode* p, BiTNode* q)
{
    Stack s1, s2;
    BiTNode* ancNode;
    init_stack(&s1);
    init_stack(&s2);

    path(root, p, &s1);
    path(root, q, &s2);

    if (s1.elem[0] != s2.elem[0])
        return NULL;

    ancNode = s1.elem[0];

    for (int i = 1; i < s1.top && i < s2.top; i++) {
        if (s1.elem[i] != s2.elem[i])
            return ancNode;
        ancNode = s1.elem[i];
    }
    return ancNode;
}

树与二叉树--树转二叉树

#include "bitree.h" //请不要删除,否则检查不通过
#include 
#include 

BiTNode* transform(CSNode* root)
{
    if (root == NULL)
        return NULL;

    //初始化二叉树的根节点
    BiTree broot = (BiTree)malloc(sizeof(struct Node));
    broot->data = root->data;
    broot->left = broot->right = NULL;

    //普通树、二叉树初始化、加入队列
    Queue* queue = create_queue();
    Queue* bqueue = create_queue();
    add_queue(queue, root);
    add_queue(bqueue, broot);

    while (!is_empty_queue(queue)) {
        //从普通数和二叉树中分别取出一个结点
        CSNode* node = del_queue(queue);
        BiTree bTreeNode = del_queue(bqueue);

        int i;
        BiTree former = NULL;
        //遍历普通树结点的所有孩子结点,将孩子加入队列
        for (i = 0; i < MAX_CHILDREN_NUM; i++) {
            //孩子非空
            if (node->children[i]) {
                //二叉树节点初始化并赋值
                BiTree bnode = (BiTree)malloc(sizeof(struct Node));
                bnode->left = bnode->right = NULL;
                bnode->data = node->children[i]->data;

                if (i == 0) //普通树的第一个孩子作为二叉树的左孩子
                    bTreeNode->left = bnode;
                else //后面的孩子结点作为前面结点的右孩子
                    former->right = bnode;
                former = bnode;

                add_queue(queue, node->children[i]);
                add_queue(bqueue, bnode);
            }
        }
    }
    free(queue->array);
    free(queue);
    free(bqueue->array);
    free(bqueue);
    return broot;
}

 

你可能感兴趣的:(数据结构与算法)