当前位置:   article > 正文

2、有序链表的维护【问题描述】编写一个程序,根据从标准输入接收的指令来维护和操作排序的链表(C语言、java和Python分别实现)_维护有序链表

维护有序链表

【问题描述】

编写一个程序,根据从标准输入接收的指令来维护和操作排序的链表。链表是按顺
序维护的,这意味着链表中的数据在每次操作后都以递增的数字顺序存储。
请注意,在创建新节点时,需要使用malloc为它们分配空间;一旦不再需要任何已
分配的空间,就应该使用free将其释放。还要注意,链表不包含重复的值。
【基本要求】
链表支持两种操作指令。
插入n :向链表中添加一个整数n。如果链表中已经存在n,则它什么也不做。 指令
格式是一个i后跟一个空格和一个整数n
删除n :从链表中删除一个整数n。如果链表中不存在n,它什么也不做。 指令格式
是d后跟一个空格和一个整数n
在每个命令之后,程序将输出链表的长度,然后是链表的内容,按照从第一个(最
小)到最后一个(最大) 的顺序。
输入格式: 输入的每一行都包含一条指令。每行都以一个字母(或者是“i”或者是
“d”)开头,后跟一个空格,然后是一个整数。以“i”开头的一行表示该整数应该插
入链表中。以“d”开头的一行表示应从链表中删除该整数。输入i和d以外的字符程序
结束运行。
输出格式: 执行每个指令后,程序将输出一行文本,其中包含 表的长度、一个冒
号以及按顺序排列的 表元素,所有内容都用空格分隔。
程序运行操作示例:(
i或d开头的行是输入行,其他是输出行
i 5
1: 5
d 3
1: 5
i 3
2: 3 5
i 500
3: 3 5 500
d 5
2: 3 500
  1. //C语言实现:
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. typedef struct ListNode {
  5. int val;
  6. struct ListNode *next;
  7. } ListNode;
  8. // 创建一个新的链表节点
  9. ListNode* createNode(int val) {
  10. ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));
  11. newNode->val = val;
  12. newNode->next = NULL;
  13. return newNode;
  14. }
  15. // 将值插入排序链表中
  16. void insert(ListNode** head, int val) {
  17. ListNode** current = head;
  18. while (*current != NULL && (*current)->val < val) {
  19. current = &((*current)->next);
  20. }
  21. if (*current == NULL || (*current)->val > val) {
  22. ListNode* newNode = createNode(val);
  23. newNode->next = *current;
  24. *current = newNode;
  25. }
  26. }
  27. // 从排序链表中删除节点
  28. void deleted(ListNode** head, int val) {
  29. ListNode** current = head;
  30. while (*current != NULL && (*current)->val != val) {
  31. current = &((*current)->next);
  32. }
  33. if (*current != NULL) {
  34. ListNode* tmp = *current;
  35. *current = (*current)->next;
  36. free(tmp);
  37. }
  38. }
  39. // 打印排序链表
  40. void print(ListNode* head) {
  41. int length = 0;
  42. ListNode* current = head;
  43. while (current != NULL) {
  44. length++;
  45. current = current->next;
  46. }
  47. printf("%d: ", length);
  48. current = head;
  49. while (current != NULL) {
  50. printf("%d ", current->val);
  51. current = current->next;
  52. }
  53. printf("\n");
  54. }
  55. // 释放链表节点动态分配的内存
  56. void freeList(ListNode* head) {
  57. while (head != NULL) {
  58. ListNode* tmp = head;
  59. head = head->next;
  60. free(tmp);
  61. }
  62. }
  63. int main() {
  64. ListNode* head = NULL;
  65. char command;
  66. int val;
  67. while (1) {
  68. scanf("%c %d", &command, &val);
  69. switch(command) {
  70. case 'i':
  71. insert(&head, val);
  72. break;
  73. case 'd':
  74. deleted(&head, val);
  75. break;
  76. default:
  77. print(head);
  78. freeList(head);
  79. return 0;
  80. }
  81. //清空输入缓存区
  82. while(getchar() != '\n');
  83. print(head);
  84. }
  85. }

 今天才看到了留言,更新一个C语言实现的代码;

这个程序通过标准输入接收两种指令,用字符变量command表示不同的指令:

- i 插入n:调用insert函数向排序链表中添加整数n;
- d 删除n:调用delete函数从排序链表中删除整数n。

每次读入指令后,用switch语句根据不同的指令调用相应的函数。排序链表的操作中,通过动态内存分配机制为新节点分配内存,并且在节点操作结束后及时释放相应的内存。链表长度和元素内容的打印依次调用print函数实现。

需要注意的是,由于输入指令时需要读入空格,为了防止在下一次读入指令时留下空格,需要在读取完输入后清空输入缓存区。此外,当输入指令字符不是i或d时,程序退出,并释放排序链表的所有分配内存。

  1. //java实现:
  2. import java.util.ArrayList;
  3. import java.util.Scanner;
  4. import java.util.LinkedList;
  5. public class demo2 {
  6. //定义一个ListNode类
  7. static class ListNode{
  8. int value;
  9. ListNode next;
  10. public ListNode(int value,ListNode next){
  11. this.value = value;
  12. this.next = next;
  13. }
  14. public ListNode(int value){
  15. this.value = value;
  16. }
  17. public ListNode(){
  18. }
  19. }
  20. public static void main(String[] args) {
  21. //把输入的字符串分割成可处理的两部分
  22. LinkedList<Integer> list = new LinkedList<>();
  23. while (true) {
  24. Scanner sc = new Scanner(System.in);
  25. String s = sc.nextLine();
  26. //分别拿到指令和数据
  27. String[] s1 = s.split(" ");
  28. char c = s1[0].charAt(0);
  29. int x = Integer.parseInt(s1[1]);
  30. //通过指令进行对应操作
  31. switch (c) {
  32. case 'I' :
  33. case 'i' : {
  34. for (int i = 0; i < list.size(); i++) {
  35. if (list.get(i).equals(x)){
  36. Object a = x;
  37. list.remove(a);
  38. }
  39. }
  40. list.add(x);
  41. list.sort(null);
  42. System.out.print(list.size()+":");
  43. for (int i = 0; i < list.size(); i++) {
  44. System.out.print(" "+list.get(i));
  45. }
  46. System.out.println();
  47. break;
  48. }
  49. case 'D':{}
  50. case 'd': {
  51. Object a = x;
  52. list.remove(a);
  53. System.out.print(list.size()+":");
  54. for (int i = 0; i < list.size(); i++) {
  55. System.out.print(" "+list.get(i));
  56. }
  57. System.out.println();
  58. break;
  59. }
  60. default : System.out.println("您输入的格式有误,请重新输入!");
  61. }
  62. }
  63. }
  64. }

 在该java程序中先定义了一个链表结构体`ListNode`,包括节点的值和指向下一个节点的指针。然后,按照题目要求,实现了链表结构的插入和删除操作,结构很好理解。

 

  1. //利用Java内置`LinkedList`实现:
  2. import java.util.ArrayList;
  3. import java.util.Scanner;
  4. import java.util.LinkedList;
  5. @SuppressWarnings("all")
  6. public class demo2 {
  7. public static void main(String[] args) {
  8. //把输入的字符串分割成可处理的两部分
  9. LinkedList<Integer> list = new LinkedList<>();
  10. while (true) {
  11. Scanner sc = new Scanner(System.in);
  12. String s = sc.nextLine();
  13. //分别拿到指令和数据
  14. String[] s1 = s.split(" ");
  15. char c = s1[0].charAt(0);
  16. int x = Integer.parseInt(s1[1]);
  17. //通过指令进行对应操作
  18. switch (c) {
  19. case 'I' :
  20. case 'i' : {
  21. for (int i = 0; i < list.size(); i++) {
  22. if (list.get(i).equals(x)){
  23. Object a = x;
  24. list.remove(a);
  25. }
  26. }
  27. list.add(x);
  28. list.sort(null);
  29. System.out.print(list.size()+":");
  30. for (int i = 0; i < list.size(); i++) {
  31. System.out.print(" "+list.get(i));
  32. }
  33. System.out.println();
  34. break;
  35. }
  36. case 'D':{}
  37. case 'd': {
  38. Object a = x;
  39. list.remove(a);
  40. System.out.print(list.size()+":");
  41. for (int i = 0; i < list.size(); i++) {
  42. System.out.print(" "+list.get(i));
  43. }
  44. System.out.println();
  45. break;
  46. }
  47. default : System.out.println("您输入的格式有误,请重新输入!");
  48. }
  49. }
  50. }
  51. }

 上述代码使用了Java内置的`LinkedList`实现相应功能。

  1. #Python实现:
  2. #定义一个链表类,内部存储val和next
  3. class Node:
  4. def __init__(self, val=0, next=None):
  5. self.val = val
  6. self.next = next
  7. #初始化链表头节点
  8. class LinkedList:
  9. def __init__(self):
  10. self.head = None
  11. #插入数字方法
  12. def insert(self, n : int):
  13. if not self.head:
  14. self.head = Node(n)
  15. return
  16. if n < self.head.val:
  17. node = Node(n)
  18. node.next = self.head
  19. self.head = node
  20. elif n > self.head.val:
  21. p = self.head
  22. while p.next and n > p.next.val:
  23. p = p.next
  24. if not p.next or n < p.next.val:
  25. node = Node(n)
  26. node.next = p.next
  27. p.next = node
  28. #删除数字方法
  29. def delete(self, n: int):
  30. if not self.head:
  31. return
  32. if self.head.val == n:
  33. self.head = self.head.next
  34. return
  35. p = self.head
  36. while p.next and p.next.val != n:
  37. p = p.next
  38. if p.next and p.next.val == n:
  39. p.next = p.next.next
  40. #打印此链表
  41. def print_list(self):
  42. p = self.head
  43. values = []
  44. while p:
  45. values.append(str(p.val))
  46. p = p.next
  47. print(len(values), ":", " ".join(values))
  48. if __name__ == "__main__":
  49. linked_list = LinkedList()
  50. while True:
  51. try:
  52. line = input().strip()
  53. if not line:
  54. continue
  55. tokens = line.split()
  56. if tokens[0] == "i":
  57. linked_list.insert(int(tokens[1]))
  58. elif tokens[0] == "d":
  59. linked_list.delete(int(tokens[1]))
  60. else:
  61. break
  62. linked_list.print_list()
  63. except EOFError:
  64. break

在Python代码中,首先定义了 `Node` 类,表示链表的节点。然后定义了 `LinkedList` 类,表示链表,它包括了插入、删除和打印链表的方法。在插入操作中,如果链表为空,将新值插入到链表头部;如果插入值小于当前链表头节点的值,则将新值插入到链表头部;否则,查找需要插入的位置,并在该位置插入新值。在删除操作中,如果链表为空或者只有一个元素,则直接从链表中删除该元素;否则,查找需要删除的元素并从链表中删除。打印链表时,遍历链表并输出每个节点的值。

在主函数中,通过读取标准输入来获取用户输入,并调用相应的方法来处理链表。当用户输入非法字符时,程序结束运行。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/709558
推荐阅读
相关标签
  

闽ICP备14008679号