1. /*
    2. * C语言风格的单向链表功能
    3. * Date: 2021/1/30
    4. * Author:phil616@126.com
    5. */
    6. #include <cstdio> //可换成stdio.h示例程序除测试输出外没有其他流操作
    7. #include <malloc.h> //C语言链表实现需要malloc库的支持,不讨论C++的情况
    8. typedef int DataType; //定义数据类型
    9. struct LinkedList
    10. {
    11. DataType data; //数据域 储存当前节点的一个数据
    12. struct LinkedList *next; //指针域 指向下一个同样类型结构体的指针
    13. // struct LinkedList *prev; //指针域 指向前一个节点,此示例为单向链表,不需要此指针
    14. };
    15. typedef LinkedList Node; //定义节点别名
    16. Node *newNode() { //新建节点函数
    17. Node *nodeptr = NULL; //储存新开辟的空间的地址指针
    18. nodeptr = (Node *)malloc(sizeof(Node)); //开辟新空间
    19. if (nodeptr == NULL) { //判断是否开辟成功
    20. printf("Memory allocate failed\n"); //分配失败报错
    21. }
    22. return nodeptr; //返回新空间的地址
    23. }
    24. Node *deleteNextNode(Node *delptr) { //删除下一个节点功能的函数,参数是要删除节点的前一个
    25. Node *fixedPtr = NULL; //定义一个固定指针并置空,该固定指针指向传入的当前节点
    26. fixedPtr = delptr; //指针固定
    27. delptr = delptr->next; //删除指针移动至要删除的节点
    28. fixedPtr->next = delptr->next; //将要删除的节点指针域传回固定指针,保持连续性
    29. free(delptr); //释放空间
    30. return fixedPtr; //返回当前节点地址
    31. }
    32. Node *releaseList(Node *releaseHead) { //析构整个链表,逐个销毁
    33. Node *movePtr = NULL; //移动指针置空
    34. for (movePtr = releaseHead; releaseHead->next != NULL; movePtr = releaseHead) {
    35. //init将移动指针固定到头节点;判断当前节点是否为最后一个节点;移动指针换位
    36. releaseHead = releaseHead->next; //当前节点换位
    37. free(movePtr); //销毁移动指针指向的节点
    38. }
    39. free(releaseHead); //如果是最后一个节点,则无法在循环中销毁,只能在循环结束后销毁
    40. return NULL;
    41. }
    42. void ShowNodeData(Node *ptr) { //数据域显示函数,用于打印数据域内的所有数据
    43. printf("%d\n", ptr->data); //当前数据域只有这一个类型
    44. }
    45. void traverseList(Node *traverseStart) { //遍历节点函数,参数是遍历头节点,从头节点开始遍历
    46. do
    47. {
    48. ShowNodeData(traverseStart); //调用显示函数,用于显示数据域的信息
    49. traverseStart = traverseStart->next;
    50. } while (traverseStart->next!=NULL);
    51. //无需返回值
    52. }
    53. DataType writeNodeData(DataType Var) { //数据域写入值封装函数
    54. return Var;
    55. }
    56. Node *swapNextTwoNode(Node *prevnode) { //节点互换函数,用于交换后面两个节点
    57. Node *ptr = prevnode;
    58. Node *fixed1, *fixed2;
    59. fixed1 = prevnode->next; //先固定两个交换的节点
    60. fixed2 = prevnode->next->next; //prevnode,fix1,fix2,next四个节点分别是1234
    61. prevnode->next = fixed2; //1节点连接3
    62. fixed1->next = fixed2->next; //2节点连接4
    63. fixed2->next = fixed1; //3节点连接2
    64. return prevnode; //连接完成返回原地址
    65. }
    66. Node *createNode(Node *pHead, int number) { //自动创造链表
    67. int i;
    68. for (i = 0; i < number; i++) {
    69. pHead->next = newNode(); //给一个首地址然后分配空间
    70. pHead->data = writeNodeData(i); //数据域写值
    71. pHead = pHead->next; //指针域连接
    72. }
    73. pHead->next = NULL; //尾指针置空
    74. return pHead;
    75. }
    76. int LinkedList() {
    77. Node *head, *ptr;
    78. head = newNode();
    79. ptr = head;
    80. ptr = createNode(head,5);
    81. swapNextTwoNode(head); //返回值被忽略
    82. traverseList(head);
    83. releaseList(head); //返回值被忽略
    84. return 0;
    85. }