C the basics (linked list)

相较数组而言,具有更好的空间效率。

单链表的各种操作:

有序单链表的插入一定要考虑清楚多种情况。

#include <stdio.h>
#include <stdlib.h>
#pragma warning (disable:4996)

typedef struct link{  ///build an undirectional linked list
    int data;
    struct link* next;
}LINK;

struct link* AppendNode(struct link* head) {
    struct link *p = NULL, *pr = head;
    int data;
    
    p = (struct link*)malloc(sizeof(struct link));
    if (p == NULL) {
        printf("No enough memory.
");
        exit(0);
    }
    if (head == NULL)
        head = p;
    else {
        while (pr->next != NULL) {
            pr = pr->next;
        }
        pr->next = p;
    }
    printf("Input a node data.
");
    scanf("%d", &data);
    p->data = data;
    p->next = NULL;
    return head;
}

void DisplayNode(struct link* head) {
    struct link* p = head;
    int j = 1;
    while (p != NULL) {
        printf("%5d%10d
", j, p->data);
        p = p->next;
        j++;
    }
}

void DeleteMemory(struct link* head) {
    struct link* p = NULL, * pr;
    p = head;
    while (p != NULL) {
        pr = p;
        free(pr);
        p = p->next;
    }
}


struct link* InsertNode(struct link* head, int nodeData)
{
    struct link* p = head, * pr = head, * temp = NULL;

    p = (struct link*)malloc(sizeof(struct link));
    if (p == NULL){
        printf("No enough meomory!
");
        exit(0);
    }
    p->next = NULL;       
    p->data = nodeData;

    if (head == NULL){
        head = p;       
    }
    else{
        while (pr->data < nodeData && pr->next != NULL){
            temp = pr;        
            pr = pr->next;   
        }
        if (pr->data >= nodeData){
            if (pr == head){
                p->next = head;   
                head = p;       
            }
            else{
                pr = temp;
                p->next = pr->next;      
                pr->next = p;         
            }
        }
        else{
            pr->next = p;   
        }
    }

    return head;
}

struct link* DeleteOneNode(struct link* head, int delete) {
    struct link* p = head, * pr = NULL;
    if (p == NULL) {
        printf("No value to delete.
");
        exit(0);
    }
    while (p->next != NULL && p->data != delete) {
        pr = p;
        p = p->next;
    }
    if (p->next == NULL && p->data != delete) {
        printf("No such value to delete.
");
        exit(0);
    }
    else if  (p == head) {
        head = p->next;
    }
    else {
        pr->next = p->next;
    }
    free(p);
    return head;
}

int main() {
    struct link* head = NULL;
    char c;
    int insert, delete;
    printf("Do you want to append a new node?
");
    scanf("%c", &c);
    
    while (c == 'y' || c == 'Y') {
        head = AppendNode(head);
        DisplayNode(head);
        printf("Do you want to append a new node?
");
        scanf(" %c", &c);
    }
    
    printf("Insert a number: ");
    scanf("%d", &insert);
    InsertNode(head, insert);
    DisplayNode(head);

    printf("Delete a number: ");
    scanf("%d", &delete);
    head = DeleteOneNode(head, delete);
    DisplayNode(head);
    DeleteMemory(head);

    return 0;
}

 一下是一个易犯的错误:

void DeleteMemory(LINK* head) {
    LINK* p = head;
    while (p != NULL) {
        free(p);
        p->fwd;
    }
}

记住!释放内存后,旧指针就没有用了!

双链表:
基本操作同单链表,注意添加一个向前指的指针。

#include <stdio.h>
#include <stdlib.h>
#pragma warning (disable:4996)

typedef struct LINK {
    struct LINK* fwd;
    struct LINK* bwd;
    int val;
}LINK;

LINK* initLINK(LINK* head) {
    LINK* p = NULL;
    head = (LINK*)malloc(sizeof(LINK));
    if (head == NULL) {
        printf("No enough memory.");
        exit(0);
    }
    head->fwd = head->bwd = NULL;
    p = head;
    for (int i = 2; i <= 3; i++) {
        LINK* temp = (LINK*)malloc(sizeof(LINK));
        if (temp == NULL) {
            printf("No enough memory.");
            exit(0);
        }
        p->fwd = temp;
        temp->bwd = p;
        temp->val = i - 1;
        p = p->fwd;
    }
    return head;
}

void displayNode(LINK* head) {
    LINK* p = head->fwd;
    while (p != NULL) {
        printf("%5d
", p->val);
        p = p->fwd;
    }
}

void deleteMemory(LINK* head) {
    LINK* p, *pr = NULL;
    p = head;
    while (p != NULL) {
        pr = p;
        free(pr);
        p = p->fwd;
    }
}

void insertNode(LINK* head, int fwd_val, int val) {//在某个数值前插入 一个节点
    LINK* p = head->fwd, * pre, *node;
    node = (LINK*)malloc(sizeof(LINK));
    if (node == NULL) {
        printf("No enough memory.");
        exit(0);
    }
    pre = p->bwd;
    while (p->val != fwd_val) {
        p = p->fwd;
        pre = p->bwd;
    }
    pre->fwd = node;
    node->fwd = p;
    node->bwd = pre;
    p->bwd = node;
    node->val = val;
}
int main() {
    LINK* head = NULL;
    head = initLINK(head);
    insertNode(head, 2, 4);
    displayNode(head);
    return 0;
}

循环链表:

首先应注意构建链表时的规范,如尾节点next指针为NULL。

双向链表添加时注意双向可添加。

原文地址:https://www.cnblogs.com/porest/p/14105156.html