数据结构习题

题目描述

有一个单链表(不同结点的数据域值可能相同),其头指针为head,编写一个函数计算数据域为x的结点个数。

运行代码

#include <stdio.h>

#include <stdlib.h>



// 定义链表节点结构体

typedef struct ListNode {

    int data;

    struct ListNode *next;

} ListNode;



// 创建新节点的辅助函数

ListNode* createNode(int val) {

    ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));

    newNode->data = val;

    newNode->next = NULL;

    return newNode;

}



// 计算数据域为 x 的结点个数

int countOccurrences(ListNode* head, int x) {

    int count = 0;

    ListNode* current = head;

    while (current != NULL) {

        if (current->data == x) {

            count++;

        }

        current = current->next;

    }

    return count;

}



// 打印链表的辅助函数

void printList(ListNode* head) {

    ListNode* current = head;

    while (current != NULL) {

        printf("%d ", current->data);

        current = current->next;

    }

    printf("\n");

}



// 释放链表内存的辅助函数

void freeList(ListNode* head) {

    ListNode* current = head;

    while (current != NULL) {

        ListNode* next = current->next;

        free(current);

        current = next;

    }

}



int main() {

    // 创建一个单链表示例

    ListNode* head = createNode(1);

    head->next = createNode(2);

    head->next->next = createNode(3);

    head->next->next->next = createNode(2);

    head->next->next->next->next = createNode(5);

    head->next->next->next->next->next = createNode(2);



    int x = 2;

    int count = countOccurrences(head, x);



    // 输出结果

    printf("链表:");

    printList(head);

    printf("数据域为 %d 的结点个数: %d\n", x, count);



    // 释放链表内存

    freeList(head);



    return 0;

}

​

代码思路

  1. 结构体 ListNode:定义了一个链表节点结构体,包含数据成员 data 和指针成员 next

  2. 函数 createNode:用于创建一个新的链表节点,并初始化其数据和指针。

  3. 函数 countOccurrences:

    • 接受两个参数:链表的头节点 head 和要计数的数据 x
    • 初始化一个计数器 count 为 0。
    • 遍历链表,如果当前节点的数据等于 x,则计数器加 1。
    • 返回计数器的值。
  4. 函数 printList:用于打印链表的内容。

  5. 函数 freeList:用于释放链表的内存,避免内存泄漏。

  6. 主函数 main:

    • 创建一个单链表示例。
    • 调用 countOccurrences 函数计算数据域为 x 的结点个数。
    • 输出链表的内容和计数结果。
    • 释放链表内存,避免内存泄漏。

题目描述

有一个有序单链表(从小到大排序),表头指针为head,编写一个函数向该单链表中插入一个元素为x的结点,使插入后该链表仍然有序。

运行代码

#include <stdio.h>

#include <stdlib.h>



// 定义链表节点结构体

typedef struct ListNode {

    int data;

    struct ListNode *next;

} ListNode;



// 创建新节点的辅助函数

ListNode* createNode(int val) {

    ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));

    newNode->data = val;

    newNode->next = NULL;

    return newNode;

}



// 将元素 x 插入到有序链表中

ListNode* insertSorted(ListNode* head, int x) {

    ListNode* newNode = createNode(x);

    if (head == NULL || x <= head->data) {

        newNode->next = head;

        return newNode;

    }



    ListNode* current = head;

    while (current->next != NULL && current->next->data < x) {

        current = current->next;

    }



    newNode->next = current->next;

    current->next = newNode;



    return head;

}



// 打印链表的辅助函数

void printList(ListNode* head) {

    ListNode* current = head;

    while (current != NULL) {

        printf("%d ", current->data);

        current = current->next;

    }

    printf("\n");

}



// 释放链表内存的辅助函数

void freeList(ListNode* head) {

    ListNode* current = head;

    while (current != NULL) {

        ListNode* next = current->next;

        free(current);

        current = next;

    }

}



int main() {

    // 创建一个有序单链表示例

    ListNode* head = createNode(1);

    head->next = createNode(3);

    head->next->next = createNode(4);

    head->next->next->next = createNode(7);



    int x = 5;

    head = insertSorted(head, x);



    // 输出链表

    printf("链表:");

    printList(head);



    // 释放链表内存

    freeList(head);



    return 0;

}

​

代码思路

  1. 结构体 ListNode:定义了一个链表节点结构体,包含数据成员 data 和指针成员 next

  2. 函数 createNode:用于创建一个新的链表节点,并初始化其数据和指针。

  3. 函数 insertSorted:

    • 接受两个参数:有序链表的头节点 head 和要插入的元素 x
    • 创建一个新节点 newNode 并初始化其数据为 x
    • 如果链表为空或 x 小于等于头节点的数据,则将新节点插入到链表头部。
    • 否则,遍历链表,找到合适的位置插入新节点,确保链表仍然有序。
    • 返回新的头节点。
  4. 函数 printList:用于打印链表的内容。

  5. 函数 freeList:用于释放链表的内存,避免内存泄漏。

  6. 主函数 main:

    • 创建一个有序单链表示例。
    • 调用 insertSorted 函数将元素 x 插入到链表中。
    • 输出链表的内容。
    • 释放链表内存,避免内存泄漏。

题目描述

编写一个函数将一个头指针为a的单链表A分解成两个单链表A和B,其头指针分别为ab,使得A链表中含有原链表A中序号为奇数的元素,而B链表中含有原链表A中序号为偶数的元素,且保持原来的相对顺序。

运行代码

#include <stdio.h>

#include <stdlib.h>



// 定义链表节点结构体

typedef struct ListNode {

    int data;

    struct ListNode *next;

} ListNode;



// 创建新节点的辅助函数

ListNode* createNode(int val) {

    ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));

    newNode->data = val;

    newNode->next = NULL;

    return newNode;

}



// 将一个链表分解成两个链表

void splitList(ListNode* a, ListNode** b) {

    if (a == NULL) {

        *b = NULL;

        return;

    }



    ListNode* odd = a;  // 奇数链表的头节点

    ListNode* even = a->next;  // 偶数链表的头节点

    *b = even;  // 将偶数链表的头节点赋值给 b



    // 遍历链表,将奇数和偶数节点分开

    while (even != NULL && even->next != NULL) {

        odd->next = even->next;  // 连接奇数节点

        odd = odd->next;

        even->next = odd->next;  // 连接偶数节点

        even = even->next;

    }

    odd->next = NULL;  // 结束奇数链表

}



// 打印链表的辅助函数

void printList(ListNode* head) {

    ListNode* current = head;

    while (current != NULL) {

        printf("%d ", current->data);

        current = current->next;

    }

    printf("\n");

}



// 释放链表内存的辅助函数

void freeList(ListNode* head) {

    ListNode* current = head;

    while (current != NULL) {

        ListNode* next = current->next;

        free(current);

        current = next;

    }

}



int main() {

    // 创建一个单链表示例

    ListNode* a = createNode(1);

    a->next = createNode(2);

    a->next->next = createNode(3);

    a->next->next->next = createNode(4);

    a->next->next->next->next = createNode(5);



    ListNode* b = NULL;

    splitList(a, &b);



    // 输出 A 链表

    printf("A 链表:");

    printList(a);



    // 输出 B 链表

    printf("B 链表:");

    printList(b);



    // 释放链表内存

    freeList(a);

    freeList(b);



    return 0;

}

​

代码思路

  1. 结构体 ListNode:定义了一个链表节点结构体,包含数据成员 data 和指针成员 next

  2. 函数 createNode:用于创建一个新的链表节点,并初始化其数据和指针。

  3. 函数 splitList:

    • 接受两个参数:原始链表的头节点 a 和一个指向指针的指针 b,用于存储拆分后的偶数位置链表的头节点。
    • 使用两个指针 odd 和 even 分别指向奇数位置和偶数位置的节点。
    • 通过遍历链表,将奇数位置和偶数位置的节点分别连接起来。
    • 最后,将 odd 的 next 指针设为 NULL,结束奇数链表。
  4. 函数 printList:用于打印链表的内容。

  5. 函数 freeList:用于释放链表的内存,避免内存泄漏。

  6. 主函数 main:

    • 创建一个示例链表 a
    • 调用 splitList 函数将链表 a 拆分为两个链表 a 和 b
    • 输出两个链表的内容。
    • 释放链表内存,避免内存泄漏。

题目描述

已知两个顺序表A和B分别表示两个集合,其元素递增排列,编写一个函数求出A和B的交集C,要求C同样以元素递增的顺序表形式存储。

运行代码

#include <stdio.h>

#include <stdlib.h>



// 函数原型声明

int* intersect(int A[], int sizeA, int B[], int sizeB, int *returnSize);



int main() {

    int A[] = {1, 2, 3, 4, 5};

    int B[] = {3, 4, 5, 6, 7};

    int sizeA = sizeof(A) / sizeof(A[0]);

    int sizeB = sizeof(B) / sizeof(B[0]);



    int returnSize;

    int *C = intersect(A, sizeA, B, sizeB, &returnSize);



    // 打印交集

    printf("Intersection: ");

    for (int i = 0; i < returnSize; i++) {

        printf("%d ", C[i]);

    }

    printf("\n");



    // 释放分配的内存

    free(C);

    return 0;

}



int* intersect(int A[], int sizeA, int B[], int sizeB, int *returnSize) {

    int *C = (int *)malloc((sizeA < sizeB ? sizeA : sizeB) * sizeof(int));

    int i = 0, j = 0, k = 0;



    while (i < sizeA && j < sizeB) {

        if (A[i] < B[j]) {

            i++;

        } else if (B[j] < A[i]) {

            j++;

        } else {

            if (k == 0 || C[k-1] != A[i]) {  // 避免添加重复的元素

                C[k++] = A[i];

            }

            i++;

            j++;

        }

    }



    *returnSize = k;

    return C;

}

​

代码思路

  1. 结构体 ListNode:

    • 定义了一个链表节点结构体,包含数据成员 data 和指针成员 next
    • 构造函数用于初始化节点的数据和指针。
  2. 函数 splitList:

    • 接受两个参数:原始链表的头节点 a 和一个引用参数 b,用于存储拆分后的偶数位置链表的头节点。
    • 使用两个指针 odd 和 even 分别指向奇数位置和偶数位置的节点。
    • 通过遍历链表,将奇数位置和偶数位置的节点分别连接起来。
    • 最后,将 odd 的 next 指针设为 nullptr,并更新 b 为 evenHead
  3. 主函数 main:

    • 创建一个示例链表 a
    • 调用 splitList 函数将链表 a 拆分为两个链表 a 和 b
    • 输出两个链表的内容。
    • 释放链表内存,避免内存泄漏。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

筱姌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值