C語言實現帶表頭節點的鏈表

數據結構及接口(Header_List.h)

#ifndef HEADER_LIST_H_INCLUDED
#define HEADER_LIST_H_INCLUDED

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

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

typedef struct HeaderList{
    Node *head;
    int Hsize;
}HeaderList;

typedef void(*PRINTNODE)(void*);   //定義函數指針,參數爲void* (任意類型的數據指針)

HeaderList* Create_HeaderList(void);
void Destroy_HeaderList(HeaderList *hlist);
void Clear_HeaderList(HeaderList *hlist);

void InsertByPos_HeaderList(HeaderList *hlist,int pos,void *newVal);
void DeleteByPos_HeaderList(HeaderList *hlist,int pos);
void* GetValByPos_HeaderList(HeaderList *hlist,int pos);
//void* FindByVal_HeaderList(HeaderList *hlist,void *data);

void Print_HeaderList(HeaderList *hlist,PRINTNODE PrintNode);
void* GetFirstVal_HeaderList(HeaderList *hlist);
int GetSize_HeaderList(HeaderList *hlist);

#endif // HEADER_LIST_H_INCLUDED

功能實現(Header_List.c)

#include "Header_List.h"

HeaderList* Create_HeaderList(void){

    HeaderList* hlist = (HeaderList*)malloc(sizeof(HeaderList));
    hlist->Hsize = 0;

    hlist->head = (Node*)malloc(sizeof(Node)); //帶表頭結點 注意表頭節點沒有標號
    hlist->head->data = NULL;
    hlist->head->next = NULL;

    return hlist;
}

void Destroy_HeaderList(HeaderList *hlist){

    if(hlist == NULL){
        fprintf(stderr,"The list is not inited(NULL),can't Destroy it.\n");
        return ;
    }

    Clear_HeaderList(hlist);

    free(hlist->head);
    free(hlist);
}

void Clear_HeaderList(HeaderList *hlist){

    while(GetSize_HeaderList(hlist) != 0)
        DeleteByPos_HeaderList(hlist,0);
}


void InsertByPos_HeaderList(HeaderList *hlist,int pos,void *newVal){

    if(hlist == NULL){
        fprintf(stderr,"The list is not inited(NULL),can't InsertByPos.\n");
        return ;
    }

    if(pos < 0  ||  pos > hlist->Hsize){
        fprintf(stderr,"parameter pos is INVALID,can't InsertByPos.\n");
        return ;
    }

    if(newVal == NULL){
        fprintf(stderr,"parameter newVal is NULL,can't InsertByPos.\n");
        return ;
    }

    Node *p = hlist->head;
    for(int i=0;i<pos;i++){
        p = p->next;
    }

    Node *newNode = (Node*)malloc(sizeof(Node));
    newNode->data = newVal;
    newNode->next = p->next;

    p->next = newNode;

    hlist->Hsize ++;
}


void DeleteByPos_HeaderList(HeaderList *hlist,int pos){

    if(hlist == NULL){
        fprintf(stderr,"The list is not inited(NULL),can't DeleteByPos.\n");
        return ;
    }

    if(pos < 0  ||  pos > hlist->Hsize-1){
        fprintf(stderr,"parameter pos is INVALID,can't DeleteByPos.\n");
        return ;
    }

    Node *q = hlist->head;
    for(int i=0;i<pos;i++){
        q = q->next;
    } // q指向要刪除節點的前一個
    Node *p = q->next;  //p指向要刪除的節點

    q->next = p->next;

    p->data = NULL;  // 先清空再釋放
    p->next = NULL;  //千萬不要free(p->data)
    free(p);    //這會導致堆內存管理出問題,也容易有漏洞

    hlist->Hsize --;
}


void* GetValByPos_HeaderList(HeaderList *hlist,int pos){

    if(hlist == NULL){
        fprintf(stderr,"The list is not inited(NULL),can't DeleteByPos.\n");
        return NULL;
    }

    if(pos < 0  ||  pos > hlist->Hsize-1){
        fprintf(stderr,"parameter pos is INVALID,can't DeleteByPos.\n");
        return NULL;
    }

    Node *p = hlist->head;
    for(int i=0;i<=pos;i++){
        p = p->next;
    }
    return p->data;
}

void Print_HeaderList(HeaderList *hlist,PRINTNODE PrintNode){

    if(hlist == NULL){
        fprintf(stderr,"The list is not inited(NULL),can't Print.\n");
    }

    Node *p = hlist->head->next;
    while(p != NULL){
        PrintNode(p->data);
        p = p->next;
    }
}

void* GetFirstVal_HeaderList(HeaderList *hlist){
    return hlist->head->next->data;
}

int GetSize_HeaderList(HeaderList *hlist){
    return hlist->Hsize;
}


功能測試(main.c)

#include "Header_List.h"
#include <windows.h>

typedef struct TEAM_MEMBER{
    char *name;
    unsigned int age;
    unsigned int rank;
} Member;

void printMember(void *data){
    Member* p = (Member*)data;
    printf("Name:%s\tAge:%d\tRank:%d\n",p->name,p->age,p->rank);
}


void test_HeaderList(){

    Member hhc_member[6];                              //注:0號作爲戰隊創始人
//專業輔助淡
    hhc_member[0].name = "zyh";
    hhc_member[0].age = 21;
    hhc_member[0].rank = 1900;
//廠長附體周
    hhc_member[1].name = "zth";
    hhc_member[1].age = 21;
    hhc_member[1].rank = 1850;
//信仰黃金鬼
    hhc_member[2].name = "zyf";
    hhc_member[2].age = 20;
    hhc_member[2].rank = 1700;
//鑽石大神濃
    hhc_member[3].name = "wyn";
    hhc_member[3].age = 20;
    hhc_member[3].rank = 2250;
//炒飯帶師嶽
    hhc_member[4].name = "yqi";
    hhc_member[4].age = 21;
    hhc_member[4].rank = 2350;
//美服高手森
    hhc_member[5].name = "wjs";
    hhc_member[5].age = 21;
    hhc_member[5].rank = 2200;

    HeaderList *hlist = Create_HeaderList();
    for(int i=0;i<6;i++)
        InsertByPos_HeaderList(hlist,i,&hhc_member[i]);

    Member *founder = GetFirstVal_HeaderList(hlist);
    Member *jungle = GetValByPos_HeaderList(hlist,1);
    printf("2012年,HHC戰隊誕生,創始人是%s\n\n",founder->name);
    printf("LOL S4-S7世界賽,HHC戰隊參賽名單如下:\n");
    Print_HeaderList(hlist,printMember);
    printf("\n");

    printf("我們有%d名隊員。\n",GetSize_HeaderList(hlist));
    printf("我們的1號選手是小廠長 %s\n",jungle->name);
    printf("\n");
    system("pause");

    system("cls");
    printf("S8賽季中期,鬼哥暫時前往AFG戰隊擔任教練,不能上場。參賽人員變更。\n\n");
    DeleteByPos_HeaderList(hlist,2);
    printf("變更後,HHC可上場人員如下:\n\n");
    Print_HeaderList(hlist,printMember);
    printf("\n");
    system("pause");

    system("cls");
    printf("\n\n某年,HHC戰隊奪得世界賽冠軍,戰隊成員光榮退役,HHC解散。\n");
    Destroy_HeaderList(hlist);
    printf("\n雖然HHC戰隊解散了,但是他們的傳說永存於世\n\n\n\n\n");
}

int main(){

    char code[18];
    char secret_code[18] = {"hhc_never_disband"};
    memset(code,0,18);
    test_HeaderList(); //HHC
    sleep(2);
    int select = MessageBoxA(NULL,TEXT("就這樣結束嗎?"),TEXT("怎麼辦"),MB_ICONINFORMATION|MB_YESNO);

    if (select == IDNO)

        fflush(stdin);
        printf("輸入神祕代碼:");
        fgets(code,18,stdin);

        if(!strcmp(code,"hhc_never_disband"))
            HHC_is_back();

    MessageBoxA(NULL,TEXT(">_<"),TEXT("GG"),MB_ICONERROR|MB_OK);


    return 0;
}

void HHC_is_back(){

    sleep(2);
    system("cls");
    system("color a");
    printf("你:不!HHC不會解散!\n\n");
    sleep(3);
    printf("隨緣:我來助你一臂之力!\n");
    printf("隨緣:兩極反轉!!!!!!\n\a");
    sleep(2);

    system("tree C:/"); //
    printf("\n\n\n\n\n\n\n\n\n\n\n\n");

    Member hhc_member[6];
//專業輔助淡
    hhc_member[0].name = "zyh";
    hhc_member[0].age = 21;
    hhc_member[0].rank = 1900;
//廠長附體周
    hhc_member[1].name = "zth";
    hhc_member[1].age = 21;
    hhc_member[1].rank = 1850;
//信仰黃金鬼
    hhc_member[2].name = "zyf";
    hhc_member[2].age = 20;
    hhc_member[2].rank = 1700;
//鑽石大神濃
    hhc_member[3].name = "wyn";
    hhc_member[3].age = 20;
    hhc_member[3].rank = 2250;
//炒飯帶師嶽
    hhc_member[4].name = "yqi";
    hhc_member[4].age = 21;
    hhc_member[4].rank = 2350;
//美服高手森
    hhc_member[5].name = "wjs";
    hhc_member[5].age = 21;
    hhc_member[5].rank = 2200;


    HeaderList *hhc = Create_HeaderList();
    for(int i=0;i<6;i++)
        InsertByPos_HeaderList(hhc,i,&hhc_member[i]);

//  printf("對不起,HHC回來了!\a\a\a\n");
    MessageBoxA(NULL,TEXT("HHC回來了!"),TEXT("不好意思"),MB_ICONWARNING|MB_OK);
    printf("HHC:\n");
    Print_HeaderList(hhc,printMember);

    exit(0);
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章