数据结构_C语言_单链表

# include <stdio.h>
# include <stdbool.h>
# include <malloc.h>

typedef int DataType;

typedef struct Node {
    DataType data;
    struct Node * next;
} Node;

/* 需要完成的所有基本操作 */
void InitList_Head(Node **);
void InitList_Tail(Node **);
int Length(Node *);
int LocateElem(Node *, DataType);
DataType GetElem(Node *, int);
bool ListInsert(Node *, int, DataType);
bool ListDelete(Node *, int, DataType *);
void PrintList(Node *);
bool Empty(Node *);
void DestroyList(Node *);

int main(void) {

    printf("-insert head-\n");
    Node * pHead1;
    InitList_Head(&pHead1);
    PrintList(pHead1);
    printf("\n");

    printf("-insert tail-\n");
    Node * pHead2;
    InitList_Tail(&pHead2);
    PrintList(pHead2);
    printf("size? %d\n", Length(pHead2));
    printf("locate 2? %d\n", LocateElem(pHead2, 6));
    printf("GetElem loc 4? %d\n", GetElem(pHead2, 4));
    printf("\n");

    printf("-insert elem-\n");
    ListInsert(pHead2, 4, 0);
    PrintList(pHead2);
    printf("\n");

    printf("-delete elem-\n");
    int e;
    ListDelete(pHead2, 4, &e);
    printf("delete elem? %d\n", e);
    PrintList(pHead2);
    printf("\n");

    printf("empty? %d\n", Empty(pHead2));
    printf("\n");

    printf("-delete elem-\n");
    DestroyList(pHead2);
    printf("empty? %d\n", Empty(pHead2));
    PrintList(pHead2);

    return 0;
}

void InitList_Head(Node ** ppHead) {
    /*
        1. 建立头结点
        2. 循环插入 (头插法)
    */

    Node * pHead = (Node *)malloc(sizeof(Node));
    /*
        此时,pHead中是头结点的地址
    */
    pHead->next = NULL;
    pHead->data = 9999; // for test

    int len = 5;
    Node * pNew;
    for (int i = 0; i < len; i++) {
        pNew = (Node *)malloc(sizeof(Node));
        pNew->data = i + 1;
        pNew->next = pHead->next;
        pHead->next = pNew;
    }

    *ppHead = pHead;
    return;
}

void PrintList(Node * pHead) {
    Node * p = pHead->next;
    int i = 0; // just for test
    /*
        注意!!!
        pHead存的是头结点的地址

        但,
        p存的不是pHead存的地址 --> 即头结点的地址
        p存的是pHead指向的那个单元中next存的地址 --> 即第一个单元的地址
    */

    printf("List's info:\n");
    while ((p != NULL) && (i <= 10)) {
        printf("data=%d, next=%d\n", p->data, p->next);
        p = p->next;

        i++;
    }

    return;
}

void InitList_Tail(Node ** ppHead) {
    Node * pHead = (Node *)malloc(sizeof(Node));
    pHead->next = NULL;
    pHead->data = 999; // just for test

    int len = 5;
    Node * pNew;
    Node * pTail = pHead;
    for (int i = 0; i < len; i++) {
        pNew = (Node *)malloc(sizeof(Node));
        pNew->data = i + 10;
        pNew->next = NULL;

        pTail->next = pNew;
        pTail = pNew;
    }

    *ppHead = pHead;
    return;
}

int Length(Node * pHead) {
    int len = 0;
    Node * p = pHead->next;

    while (p != NULL) {
        len++;
        p = p->next;
    }

    return len;
}

int LocateElem(Node * pHead, DataType d) {
    int loc = 0;
    Node * p = pHead->next;

    while (p != NULL && p->data != d) {
        /*
            四种情况:
            p == NULL && p->data == d --> 跳出循环 --> 尾结点是目标点
            p == NULL && p->data != d --> 跳出循环 --> 没有目标点
            p != NULL && p->data == d --> 跳出循环 --> 尾结点前是目标点
            p != NULL && p->data != d --> 继续循环
        */
        p = p->next;
        loc++;
    }

    if (p == NULL || p->data != d) {
        /*
            判定条件不能只写(p->data != d)
            因为,若此时p是NULL,则不能访问p->data
        */
        return -1; // 没有这个点
    }

    return loc;
}

DataType GetElem(Node * pHead, int pos) {
    Node * p = pHead->next;
    int i = 1;

    if (pos <= 0) return -888;

    while(p != NULL) {

        if (i == pos) {
            return p->data;
        }

        p = p->next;
        i++;

    }

    return -999;
}

bool ListInsert(Node * pHead, int pos, DataType d) {
    if (pos <= 0) return false;

    Node * p = pHead->next;
    Node * pPrior = pHead;
    int i = 1;

    while(p != NULL) {
        if (i == pos) {
            Node * pNew = (Node * )malloc(sizeof(Node));
            pNew->data = d;
            pNew->next = p;
            pPrior->next = pNew;

            return true;
        }

        p = p->next;
        pPrior = pPrior->next;
        i++;
    }

    return false;
}

bool ListDelete(Node * pHead, int pos, DataType * d) {
    if (pos <= 0) return false;

    Node * p = pHead->next;
    Node * pPrior = pHead;
    int i = 1;

    while (p != NULL) {
        if (i == pos) {
            *d = p->data;
            pPrior->next = p->next;

            free(p);
            p=NULL;

            return true;
        }

        p = p->next;
        pPrior = pPrior->next;
        i++;
    }

    return false;
}

bool Empty(Node * pHead) {
    if (pHead->next == NULL) return true;

    return false;
}

void DestroyList(Node * pHead) {
    pHead->next = NULL;
}

 

posted @ 2019-03-22 20:57  daheww  阅读(153)  评论(0编辑  收藏  举报