• 数据结构实验2


    1、分别创建两个有序的单链表(每个表的元素个数以及每个元素的值在运行时由键盘输入),现将两个单链表合并,并保证新表依然为有序的单链表。

    1. #include
    2. #include
    3. // 定义单链表结构体
    4. typedef struct ListNode {
    5. int data;
    6. struct ListNode *next;
    7. } ListNode;
    8. //创建一个单链表,返回头节点的指针
    9. ListNode* createList() {
    10. ListNode *head = NULL, *p = NULL, *q = NULL;
    11. int n = 0, data = 0;
    12. printf("请输入要创建单链表的长度:");
    13. scanf("%d", &n);
    14. // 依次读入每个元素,创建新的节点,并插入链表尾部
    15. for (int i = 1; i <= n; ++i) {
    16. printf("请输入第%d个节点值:", i);
    17. scanf("%d", &data);
    18. // 创建新节点
    19. p = (ListNode*) malloc(sizeof(ListNode));
    20. p->data = data;
    21. p->next = NULL;
    22. // 插入链表尾部
    23. if (head == NULL) {
    24. head = p;
    25. } else {
    26. q = head;
    27. while (q->next != NULL) {
    28. q = q->next;
    29. }
    30. q->next = p;
    31. }
    32. }
    33. return head;
    34. }
    35. //合并两个有序的单链表,返回合并后的链表头节点的指针
    36. ListNode* mergeLists(ListNode* list1, ListNode* list2) {
    37. if (list1 == NULL) {
    38. return list2;
    39. }
    40. if (list2 == NULL) {
    41. return list1;
    42. }
    43. // 创建哨兵节点,简化代码逻辑
    44. ListNode sentinel = {0, NULL};
    45. ListNode *tail = &sentinel;
    46. // 依次比较两个链表的节点,并将较小的节点插入新的链表尾部
    47. while (list1 != NULL && list2 != NULL) {
    48. if (list1->data <= list2->data) {
    49. tail->next = list1;
    50. list1 = list1->next;
    51. } else {
    52. tail->next = list2;
    53. list2 = list2->next;
    54. }
    55. tail = tail->next;
    56. }
    57. // 将剩余节点插入新链表尾部
    58. if (list1 != NULL) {
    59. tail->next = list1;
    60. }
    61. if (list2 != NULL) {
    62. tail->next = list2;
    63. }
    64. // 返回哨兵节点的下一个节点作为新链表头节点
    65. return sentinel.next;
    66. }
    67. //遍历单链表,并打印每个节点的值
    68. void traverseList(ListNode* head) {
    69. printf("合并后单链表:");
    70. while (head != NULL) {
    71. printf("%d ", head->data);
    72. head = head->next;
    73. }
    74. printf("\n");
    75. }
    76. int main() {
    77. ListNode *list1 = createList();
    78. ListNode *list2 = createList();
    79. ListNode *mergedList = mergeLists(list1, list2);
    80. traverseList(mergedList);
    81. return 0;
    82. }

    各个函数的实现流程:

    1. createList

    用于创建一个单链表,返回头节点的指针。先读入要创建的链表长度,然后依次读入每个节点的值,创建新节点,并将其插入到链表尾部。需要注意的是,在第一次插入节点时,需要将头节点指针指向该节点。

    2. mergeLists

    用于合并两个有序的单链表,返回合并后的链表头节点的指针。如果其中一个链表为空,则直接返回另一个链表头节点的指针。为了简化代码逻辑,该函数先创建一个哨兵节点,指向新链表的头节点。然后依次比较两个链表的节点值,将较小的节点插入到新链表尾部。最后将剩余节点直接接到新链表尾部。

    3. traverseList

    用于遍历单链表,并打印每个节点的值。只需从头节点开始依次遍历每个节点,输出其数据域的值即可。

     

    2、创建以单链表存放的两个多项式(为便于测试,每项的系数和指数可放在结点的结构体中),求二者之和,结果存放在第三个链表中。

    1. #include
    2. #include
    3. // 定义单链表结构体
    4. typedef struct ListNode {
    5. int coef;
    6. int expn;
    7. struct ListNode *next;
    8. } ListNode;
    9. //创建一个单链表,返回头节点的指针
    10. ListNode* createList() {
    11. ListNode *head = NULL, *p = NULL, *q = NULL;
    12. int n = 0, coef = 0, expn = 0;
    13. printf("请输入单链表的长度:");
    14. scanf("%d", &n);
    15. // 依次读入每个元素,创建新的节点,并插入链表尾部
    16. for (int i = 1; i <= n; ++i) {
    17. printf("请输入第%d个节点的系数和指数,中间以空格分隔:", i);
    18. scanf("%d %d", &coef, &expn);
    19. // 创建新节点
    20. p = (ListNode*) malloc(sizeof(ListNode));
    21. p->coef = coef;
    22. p->expn = expn;
    23. p->next = NULL;
    24. // 插入链表尾部
    25. if (head == NULL) {
    26. head = p;
    27. } else {
    28. q = head;
    29. while (q->next != NULL) {
    30. q = q->next;
    31. }
    32. q->next = p;
    33. }
    34. }
    35. return head;
    36. }
    37. //遍历单链表,并打印每个节点的值
    38. void traverseList(ListNode* head) {
    39. printf("遍历单链表:");
    40. while (head != NULL) {
    41. printf("%dx^%d+ ", head->coef, head->expn);
    42. head = head->next;
    43. }
    44. printf("\n");
    45. }
    46. //实现两个多项式的加法,返回新链表头节点的指针
    47. ListNode* addPolynomials(ListNode* poly1, ListNode* poly2) {
    48. ListNode sentinel = {0, 0, NULL};
    49. ListNode *tail = &sentinel;
    50. while (poly1 != NULL && poly2 != NULL) {
    51. if (poly1->expn < poly2->expn) {
    52. // 创建新节点,并插入尾部
    53. ListNode *p = (ListNode*) malloc(sizeof(ListNode));
    54. p->coef = poly1->coef;
    55. p->expn = poly1->expn;
    56. p->next = NULL;
    57. tail->next = p;
    58. tail = tail->next;
    59. poly1 = poly1->next;
    60. } else if (poly1->expn > poly2->expn) {
    61. // 创建新节点,并插入尾部
    62. ListNode *p = (ListNode*) malloc(sizeof(ListNode));
    63. p->coef = poly2->coef;
    64. p->expn = poly2->expn;
    65. p->next = NULL;
    66. tail->next = p;
    67. tail = tail->next;
    68. poly2 = poly2->next;
    69. } else {
    70. int sum = poly1->coef + poly2->coef;
    71. if (sum != 0) {
    72. // 创建新节点,并插入尾部
    73. ListNode *p = (ListNode*) malloc(sizeof(ListNode));
    74. p->coef = sum;
    75. p->expn = poly1->expn;
    76. p->next = NULL;
    77. tail->next = p;
    78. tail = tail->next;
    79. }
    80. poly1 = poly1->next;
    81. poly2 = poly2->next;
    82. }
    83. }
    84. // 插入未处理完的节点
    85. if (poly1 != NULL) {
    86. tail->next = poly1;
    87. }
    88. if (poly2 != NULL) {
    89. tail->next = poly2;
    90. }
    91. // 删除哨兵节点,返回新链表头节点
    92. ListNode *result = sentinel.next;
    93. free(&sentinel);
    94. return result;
    95. }
    96. int main() {
    97. ListNode *poly1 = createList();
    98. ListNode *poly2 = createList();
    99. traverseList(poly1);
    100. traverseList(poly2);
    101. ListNode *result = addPolynomials(poly1, poly2);
    102. traverseList(result);
    103. return 0;
    104. }

    每个函数的实现流程:

    1. `createList()`: 创建一个单链表,并返回头节点的指针。
       - 首先通过用户输入获取需要创建的单链表的长度。
       - 然后使用循环逐个读入每个节点的系数和指数。
       - 每次读入一个节点时,创建新的节点并赋值,然后插入到链表尾部。
       - 循环结束后返回头节点的指针。

    2. `traverseList(ListNode* head)`: 遍历链表,并打印每个节点的系数和指数。
       - 通过循环遍历链表中的每个节点。
       - 对于每个节点,打印其系数和指数。
       - 循环结束后输出换行符。

    3. `addPolynomials(ListNode* poly1, ListNode* poly2)`: 实现两个多项式的加法,并返回新链表的头节点指针。
       - 创建一个哨兵节点 sentinel 作为新链表的头节点前面的辅助节点。
       - 使用一个指针 tail 指向新链表的尾部节点,初始化为哨兵节点。
       - 使用循环遍历 poly1 和 poly2 两个链表,比较当前节点的指数大小进行处理。
       - 如果 poly1 的指数小于 poly2 的指数,将 poly1 的节点添加到新链表中,并更新 tail 指针和 poly1 指针。
       - 如果 poly1 的指数大于 poly2 的指数,将 poly2 的节点添加到新链表中,并更新 tail 指针和 poly2 指针。
       - 如果 poly1 和 poly2 的指数相等,计算两个系数的和 sum,如果 sum 不为 0,则创建新节点并添加到新链表中,并更新 tail 指针。
       - 循环结束后,将未处理完的节点添加到新链表的尾部。
       - 最后,删除哨兵节点,返回新链表的头节点指针。

     

  • 相关阅读:
    【ORACLE】什么时候ROWNUM等于0和ROWNUM小于0,两个条件不等价?
    单目标优化算法:火鹰优化算法(Fire Hawk Optimizer,FHO)求解23个函数--提供MATLAB代码
    Torch not compiled with CUDA enabled
    手把手教你Nginx常用模块详解之ngx_stream_ssl_module(七)
    【Android入门】6、ContentProvider:跨程序的数据共享:访问其他 App、被其他 App 访问
    一个方法用js生成随机双色球、大乐透
    Blazor组件自做十一 : File System Access 文件系统访问 组件
    计算机毕设(附源码)JAVA-SSM楼盘销售管理系统
    后缀表达式求值
    JavaScript学习Day001
  • 原文地址:https://blog.csdn.net/weixin_74384251/article/details/133943960