单向链表增删改查

#include "library.h"

#include <stdio.h>
#include <stdlib.h>

typedef struct Node {
    int data;
    struct Node* next;
} Node;
typedef void (*callback)(Node* node);
void traverse(Node* head, callback f);

Node* create(int data, Node* next);
Node* prepend(Node* head, int data);
Node* append(Node* head, int data);
Node* insert_after(Node* head, int data, Node* prev);
Node* insert_before(Node* head, int data, Node* nxt);
Node* reverse(Node* head);
Node* search(Node* head, int data);
Node* remove_front(Node* head);
Node* remove_back(Node* head);
Node* remove_any(Node* head,Node* nd);
void dispose(Node *head);
int countNode(Node* head);
void display(Node* n);
void menu();


int main() {
    int command = 0;
    int data;
    Node* head = NULL;
    Node* tmp = NULL;
    callback disp = display;
    menu();
    while (1) {
        printf("\nEnter a command(0-10,-1 to quit):");
        scanf("%d",&command);

        if(command == -1) break;
        switch(command)
        {
            case 0:
                menu();
                break;
            case 1:
                printf("Please enter a number to prepend:");
                scanf("%d",&data);
                head = prepend(head,data);
                traverse(head,disp);
                break;
            case 2:
                printf("Please enter a number to append:");
                scanf("%d",&data);
                head = append(head,data);
                traverse(head,disp);
                break;
            case 3:
                printf("Please enter a number to search:");
                scanf("%d",&data);
                tmp = search(head,data);
                if(tmp != NULL)
                {
                    printf("Element with value %d found.",data);
                }
                else
                {
                    printf("Element with value %d not found.",data);
                }
                break;
            case 4:
                printf("Enter the element value where you want to insert after:");
                scanf("%d",&data);
                tmp = search(head,data);
                if(tmp != NULL)
                {
                    printf("Enter the element value to insert after:");
                    scanf("%d",&data);
                    head = insert_after(head,data,tmp);
                    if(head != NULL)
                        traverse(head,disp);
                }
                else
                {
                    printf("Element with value %d not found.",data);
                }
                break;
            case 5:
                printf("Enter the element value where you want to insert before:");
                scanf("%d",&data);
                tmp = search(head,data);
                if(tmp != NULL)
                {
                    printf("Enter the element value to insert before:");
                    scanf("%d",&data);
                    head = insert_before(head,data,tmp);

                    if(head != NULL)
                        traverse(head,disp);
                }
                else
                {
                    printf("Element with value %d not found.",data);
                }
                break;
            case 6:
                head = remove_front(head);
                if(head != NULL)
                    traverse(head,disp);
                break;
            case 7:
                head = remove_back(head);
                if(head != NULL)
                    traverse(head,disp);
                break;
            case 8:
                printf("Enter the element value to remove:");
                scanf("%d",&data);
                tmp = search(head,data);
                if(tmp != NULL)
                {
                    remove_any(head,tmp);
                    if(head != NULL)
                        traverse(head,disp);
                }
                else
                {
                    printf("Element with value %d not found.",data);
                }
                break;
            case 9:
                head = reverse(head);
                if(head != NULL)
                    traverse(head,disp);
                break;
            case 10:
                printf("the elements count of a linked list is %d\n", countNode(head));
        }
    }
    dispose(head);

    return 0;
}

void menu()
{
    printf("--- C Linked List Demonstration --- \n\n");
    printf("0.menu\n");
    printf("1.prepend an element\n");
    printf("2.append an element\n");
    printf("3.search for an element\n");
    printf("4.insert after an element\n");
    printf("5.insert before an element\n");
    printf("6.remove front node\n");
    printf("7.remove back node\n");
    printf("8.remove any node\n");
    printf("9.Reverse the linked list\n");
    printf("10.Count the elements of a linked list\n");
    printf("-1.quit\n");

}

Node* create(int data, Node* next) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    // 分配失败
    if (newNode == NULL) {
        printf("Error creating a new node.\n");
        exit(0);
    }
    newNode->data = data;
    newNode->next = next;

    return newNode;
}

Node* prepend(Node* head, int data) {
    Node* newNode = create(data, head);
    head = newNode;
    return head;
}
// 遍历链表
void traverse(Node* head, callback f) {
    Node* pointer = head;
    while (pointer) {
        // f函数用于在遍历是操作节点数据
        f(pointer);
        pointer = pointer->next;
    }
}
//统计链表的元素
int countNode(Node* head) {
    int cut = 0;
    Node* pointer = head;
    while (pointer) {
        cut++;
        pointer = pointer->next;
    }
    return cut;
}
// 在链表的末尾添加一个新节点
Node* append(Node* head, int data) {
    if(head == NULL)
        return NULL;

    Node* pointer = head;
    while (pointer->next) {
        pointer = pointer->next;
    }
    Node* newNode = create(data, NULL);
    pointer->next = newNode;
    return head;
}
// 在特定节点之后插入一个新节点
Node* insert_after(Node* head, int data, Node* prev) {
    Node* pointer = head;
    while (pointer != prev) {
        pointer =pointer->next;
    }
    if (pointer) {
        Node* newNode = create(data, pointer->next);
        pointer->next = newNode;
        return head;
    } else {
        return NULL;
    }
}
// 在特定节点之前插入一个新节点
Node* insert_before(Node* head, int data, Node* nxt) {
    if ( nxt == NULL || head == NULL) return NULL;
    if (head == nxt) {
        head = prepend(head, data);
        return head;
    }
    Node* pointer = head;
    while (pointer) {
        if (pointer->next == nxt) break;
        pointer = pointer->next;
    }
    if (pointer) {
        Node* newNode = create(data, pointer->next);
        pointer->next = newNode;
        return head;
    } else {
        return NULL;
    }
}
// 搜索节点
Node* search(Node* head, int data) {
    Node* pointer = head;
    while (pointer) {
        if ( pointer->data == data) return pointer;
        pointer = pointer->next;
    }
    return NULL;
}
// 反向链表
Node* reverse(Node* head) {
    Node* prev = NULL;
    Node* current = head;
    Node* next;
    while (current) {
        next = current->next;
        current->next = prev;
        prev = current;
        current = next;
    }
    head = prev;
    return head;
}
//从链表的前面删除一个节点
Node* remove_front(Node* head) {
    if(head == NULL) return NULL;
    Node* pointer = head;
    head = head->next;
    pointer->next = NULL;
    // 如果列表只有一个节点,应该将head 指针设置为NULL。
    if (pointer == head) head = NULL;
    free(pointer);
    return head;
}
//从链表的后面删除一个节点
Node* remove_back(Node* head) {
    if (head == NULL) return NULL;
    Node* pointer = head;
    Node* back = NULL;
    while (pointer->next) {
        back = pointer;
        pointer = pointer->next;
    }
    if (back) {
        back->next = NULL;
    }
    /* if this is the last node in the list*/
    if (pointer == head) head = NULL;
    free(pointer);
    return head;
}
// 删除链表中间的节点
Node* remove_any(Node* head,Node* nd) {
    /* if the node is the first node */
    if (nd == head) {
        head = remove_front(head);
        return head;
    }
    /* if the node is the last node */
    if (nd->next == NULL) {
        head = remove_back(head);
        return head;
    }
    Node* pointer = head;
    while (pointer) {
        if (pointer->next == nd)  break;
        pointer = pointer->next;
    }
    if (pointer) {
        Node* t = pointer->next;
        pointer->next = t->next;
        free(t);
    }
    return head;
}
//删除整个链表
void dispose(Node *head) {
    Node *pointer, *tmp;
    if (head) {
        pointer = head->next;
        head->next = NULL; // 并没有释放head指针所占的内存
        while (pointer) {
            tmp = pointer->next;
            free(pointer);
            pointer = tmp;
        }
    }
}
void display(Node* n)
{
    if(n != NULL)
        printf("%d ", n->data);
}

--- C Linked List Demonstration --- 

0.menu
1.prepend an element
2.append an element
3.search for an element
4.insert after an element
5.insert before an element
6.remove front node
7.remove back node
8.remove any node
9.Reverse the linked list
10.Count the elements of a linked list
-1.quit

Enter a command(0-10,-1 to quit):1
Please enter a number to prepend:1

Enter a command(0-10,-1 to quit):1
Please enter a number to prepend:3
3 1 
Enter a command(0-10,-1 to quit):1
Please enter a number to prepend:2
2 3 1 
Enter a command(0-10,-1 to quit):1
Please enter a number to prepend:5
5 2 3 1 
Enter a command(0-10,-1 to quit):2
Please enter a number to append:6
5 2 3 1 6 
Enter a command(0-10,-1 to quit):2
Please enter a number to append:9
5 2 3 1 6 9 
Enter a command(0-10,-1 to quit):2
Please enter a number to append:8
5 2 3 1 6 9 8 
Enter a command(0-10,-1 to quit):2
Please enter a number to append:0
5 2 3 1 6 9 8 0 
Enter a command(0-10,-1 to quit):3
Please enter a number to search:2
Element with value 2 found.
Enter a command(0-10,-1 to quit):3
Please enter a number to search:4
Element with value 4 not found.
Enter a command(0-10,-1 to quit):4
Enter the element value where you want to insert after:3
Enter the element value to insert after:4
5 2 3 4 1 6 9 8 0 
Enter a command(0-10,-1 to quit):5
Enter the element value where you want to insert before:1
Enter the element value to insert before:-1
5 2 3 4 -1 1 6 9 8 0 
Enter a command(0-10,-1 to quit):6
2 3 4 -1 1 6 9 8 0 
Enter a command(0-10,-1 to quit):7
2 3 4 -1 1 6 9 8 
Enter a command(0-10,-1 to quit):8
Enter the element value to remove:1
2 3 4 -1 6 9 8 
Enter a command(0-10,-1 to quit):9
8 9 6 -1 4 3 2 
Enter a command(0-10,-1 to quit):10
the elements count of a linked list is 7

Enter a command(0-10,-1 to quit):-1

进程已结束,退出代码0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

1planet

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

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

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

打赏作者

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

抵扣说明:

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

余额充值