資料結構——單鍵表操作集

CPPigSnail發表於2020-12-06

單連結串列由多個結點構成,每個結點有資料域和指標域。指標域指向其後繼的結點。最後一個結點的指標指向NULL。
在這裡插入圖片描述

頭結點的資料域存放長度。
標頭檔案head.h

#ifndef _HEAD_H
#define _HEAD_H

typedef struct node* List;
typedef int ElementType;

typedef struct node {
    ElementType data;
    List next;
}Node;
/*建立連結串列, 表長為length*/
List CreateList(int length);
/*插入資料*/
void InsertNode(List head, int n);
/*刪除資料*/
void DeleteNode(List head, int n);
/*修改資料*/
void ModifyNode(List head, int n);
/*查詢資料*/
List FindData(const Node* head, ElementType n);
/*釋放記憶體*/
void FreeSpace(List head);
/*顯示*/
void Display(const Node* head);
/*清除緩衝區*/
void clean(void);
/*判斷是空*/
int IsEmpty(const Node* head);
/*輸入函式,加了輸入限制保證不越界*/
int Input(const Node* l);

#endif

主函式main.c

#include<stdio.h>
#include"operation.c"
#include"head.h"

int main(void)
{
    int location = 0;
    printf("建立一個初始連結串列,你想有幾個結點:\n");
    int n;
    scanf("%d", &n);
    clean();
    List head = CreateList(n);
    Display(head);

    puts("*****************************************");
    printf("插入操作\n");
    location = Input(head);
    InsertNode(head, location - 1); 
    Display(head);

    puts("*****************************************");
    printf("刪除操作\n");
    location = Input(head);
    DeleteNode(head, location - 1); 
    Display(head);
    puts("*****************************************");

    puts("*****************************************");
    printf("修改操作\n");
    location = Input(head);
    ModifyNode(head, location - 1); 
    Display(head);
    puts("*****************************************");

    puts("*****************************************");
    printf("查詢操作\n");
    ElementType find;
    printf("輸入你要查詢的值:");
    scanf("%d", &find);
    clean();
    List p = FindData(head, find);
    printf("%d\n", p == NULL ? printf("沒有這個資料\n") : p->data);
    puts("*****************************************");

    puts("*****************************************");
    Display(head);
    puts("*****************************************");

    FreeSpace(head);

    return 0;
}
                                

操作集operation.c不考慮分配不到記憶體的情況。

#include"head.h"
#include<time.h>
#include<stdlib.h>
#include<stdio.h>

List CreateList(int length)
{
    srand((unsigned int)time(0)); //種子設定為系統時間
    List head = (List)malloc(sizeof(Node)); //頭結點,準確來說head是指向頭結點的頭指標,但是這裡頭結點也是malloc的了。如果有必要可以在主函式裡Node head一個頭結點。
    head->data = 0;
    head->next = NULL;
    List record = head;

    while(length--)
    {
        List p = (List)malloc(sizeof(Node));
        p->data = rand() % 10; //生成不大於10的隨機種子
        p->next = NULL;

        record->next = p;
        record = p;
        head->data++;
    }
    return head;
}
int Input(const Node* l)
{
    printf("選擇位置:");
    int location;
    while(scanf("%d", &location))
    {
        if (location > 0 && location <= l->data)
            break;
        printf("選擇位置, 不小於1, 不大於%d:", l->data);
        clean();
    }
    clean();
    return location;
}
void InsertNode(List head, int n)
{
    while(n--)
    {
        head = head->next;
    }

    List p = (List)malloc(sizeof(Node));
    printf("插入的值:\n");
    scanf("%d", &p->data);
    clean();
    p->next = head->next;
    head->next = p;
    head->data++;
}
void DeleteNode(List head, int n)
{
    List h = head;
    List front = head;
    head = head->next; //head指向第一個有效值的位置
    while(n--)
    {
        front = head;
        head = head->next;
    }
    front->next = head->next;
    free(head);
    h->data--;
}
void ModifyNode(List head, int n)
{
    List l = head->next;
    while(n--)
    {
        l = l ->next;
    }
    printf("要修改的值:\n");
    scanf("%d", &l->data);
}
List FindData(const Node* head, ElementType n)
{
    List l = head->next;
    while(l)
    {
        if (l->data == n)
            return l;
        l = l->next;
    }
    printf("沒有這個資料\n");
    return NULL;
}
void FreeSpace(List head)
{
    List p = head->next;
    List q = head;
    while(p)
    {
        q = p->next;
        free(p);
        p = q;
    }
    free(head);
}
void Display(const Node* head)
{
    int length = head->data;
    if (IsEmpty(head))
    {
        printf("Is Empty");
		exit(EXIT_FAILURE);
    }
    List l = head->next;
    /*
    for (int i = 1; l; i++)
    {
        printf("%2d", l->data);
        l = l->next;
        if (i % 10 == 0)
        {
            printf("\n");
            i = 0;
        }
    }
    */
    for (int i = 1; i <= length; i++)
    {
        printf("%2d", l->data);
        if (i != length) //表示到達最後一個
            printf("->");
        l = l->next;
    }

    printf("\n");
    return ;
}
void clean(void)
{
    while(getchar() != '\n')
        continue;
}
int IsEmpty(const Node* head)
{
    return head->next == NULL;
}

在這裡插入圖片描述

相關文章