1. 程式人生 > >c實現功能(13)實現單向連結串列的簡要功能

c實現功能(13)實現單向連結串列的簡要功能

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

//利用結構體建立節點
struct list{
    //建立資料域
    int data;
    //建立指標域
    struct list *next;
};

//實現建立一個節點的方法
struct list *create_list(){
    return calloc(sizeof (struct list), 1);
}

//迴圈遍歷連結串列
void traverse(struct list *ls){
    struct list *p = ls;

    while(p){
        printf("%d\n", p->data);
        p = p->next;
    }
}

//在指定的位置插入元素
struct list *insert_list(struct list *ls, int n, int data){
    struct list *p = ls;
    //這裡做的是遍歷到要插入的節點
    while (p && n--) {
        p = p->next;
    }
    //說明n大於連結串列的節點數
    if(p == NULL){
        return NULL;
    }

    //建立一個新的節點
    struct list *node = create_list();
    node->data = data;
    //先後再前
    node->next = p->next;
    p->next = node;
}

//刪除指定位置的元素
int delete_list(struct list *ls, int n){
    struct list *p = ls;
    while(p && n--){
        p = p->next;
    }

    if(p == NULL){
        //n的位置不合適
        return -1;
    }

    struct list *temp = p->next;
    p->next = p->next->next;
    free(temp);

    return 0;
}

//返回連結串列元素的個數
int count_list(struct list *ls){
    struct list *p = ls;
    int count = 0;
    while(p){
        count++;
        p = p->next;
    }

    return count;
}

//清空連結串列,只保留首節點
void clear_list(struct list *ls){
    //因為要保留首節點,所以起始的位置為第二個節點
    struct list *p = ls->next;
    while(p){
        struct list *temp = p->next;
        free(p);
        p = temp;
    }

    //將首節點的下一個節點設定為null
    ls->next = NULL;
}

//檢視連結串列是否為空
int empty_list(struct list *ls){
    if(ls->next){
        return 0;
    }else{
        return -1;
    }
}

//返回連結串列指定位置的節點
struct list *locale_list(struct list *ls, int n){
    struct list *p = ls;
    while(p && n--){
        p = p->next;
    }

    if(p == NULL){
        return NULL;
    }

    return p;
}

//通過資料域尋找指標域,返回節點在連結串列中的位置
int data_list(struct list *ls, int data){
    int index = 1;
    struct list *p = ls;
    while(p){
        if(p->data == data){
            return index;
        }else{
            p = p->next;
        }
        index++;
    }

    return 0;
}

//得到最後一個節點
struct list *last_list(struct list *ls){
    struct list *p = ls;
    while(p->next){
        p = p->next;
    }

    return p;
}

//合併兩個連結串列,但不合並連結串列頭
void merge_list(struct list *ls1, struct list *ls2){
    last_list(ls1)->next = ls2->next;
    //連結串列頭並不合併
    free(ls2);
}

int main(void){
    //在堆中建立一個節點
    struct list *first = create_list();
    struct list *second = create_list();
    struct list *third = create_list();

    first->next = second;
    second->next = third;
    third->next = NULL;

    first->data = 1;
    second->data = 2;
    third->data = 3;

    //測試遍歷連結串列
    traverse(first);
    printf("---------------------\n");

    //測試插入資料
    insert_list(first, 1, 4);
    traverse(first);
    printf("---------------------\n");

    //測試刪除元素
    delete_list(first, 1);
    traverse(first);
    printf("---------------------\n");

    //測試返回元素的個數
    int count = count_list(first);
    printf("測試返回元素的個數: %d\n", count);
    printf("---------------------\n");

    //測試返回指定位置的節點
    struct list *p = locale_list(first, 1);
    printf("測試返回指定位置的節點: %d\n", p->data);
    printf("---------------------\n");

    //測試通過資料域查詢指標域
    if(data_list(first, 1)){
        printf("Find\n");
    }else{
        printf("Not Find\n");
    }
    printf("%d\n", data_list(first, 4));
    printf("---------------------\n");

    //測試得到最後一個節點
    printf("最後一個節點: %d\n", last_list(first)->data);
    printf("---------------------\n");

    //測試清空連結串列
    clear_list(first);
    traverse(first);
    printf("---------------------\n");

    //測試合併兩個連結串列
    struct list *first2 = create_list();
    for(int i = 0; i < 10; i++){
        insert_list(first, 0, i);
    }

    merge_list(first, first2);
    traverse(first);
    printf("---------------------\n");

    return 0;
}