單鏈表的創建、插入、刪除和反轉操作

#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct List
{

    ElemType data;      //數據域
    struct List *next;  //指針域
} Node, *LinkedList;

//頭插法創建鏈表,將新增節點插頭第一個節點之前
LinkedList createH()
{
    Node *L = (Node *)malloc(sizeof(Node));     //申請一個數據域爲空的頭節點
    if(L == NULL)
    {
        printf("分配空間失敗!\n");
        exit(0);
    }
    L->next = NULL;
    int nodeNum;
    printf("輸入節點數量: ");
    scanf("%d",&nodeNum);
    printf("\n");
    printf("輸入節點數據: ");
    for(int i=0; i<nodeNum; i++)        //依次插入節點
    {
        ElemType data;
        scanf("%d",&data);
        Node *p = (Node *)malloc(sizeof(Node));     //申請節點空間
        if(p == NULL)
        {
            printf("分配空間失敗!\n");
            exit(0);
        }
        p->data = data;
        p->next = L->next;          //頭結點指向新增節點
        L->next = p;                //新增節點指向第一個節點
    }
    return L;                       //返回頭節點

}


//尾插法建立鏈表,新增節點插入最後一個節點之後
LinkedList createT()
{
    Node *L, *pre;
    L = (Node*)malloc(sizeof(Node));         //爲頭結點申請空間
    if(L == NULL)                           //判斷是否申請失敗
    {
        printf("申請內存失敗!\n");
        exit(0);
    }
    L->next = NULL;
    pre = L;                                //pre始終指向鏈表尾部
    int nodeNum;
    printf("輸入節點數量: ");
    scanf("%d",&nodeNum);
    printf("\n");
    printf("輸入節點數據: ");
    ElemType data;
    for(int i=0; i<nodeNum; i++)
    {
        scanf("%d",&data);
        Node *p = (Node *)malloc(sizeof(Node));     //爲新增節點分配空間
        if(p == NULL)
        {
            printf("申請內存失敗!\n");
            exit(0);
        }
        p->data = data;
        p->next = NULL;
        pre->next = p;          //新增節點插入鏈表尾部
        pre = pre->next;        //pre移到尾部
    }
    return L;
}





//在指定位置插入節點
void insertNode(LinkedList L)
{
    int pos;                //插入位置
    ElemType data;          //插入節點數據
    printf("輸入插入位置, 插入節點的數據: ");
    scanf("%d %d",&pos,&data);
    LinkedList p = L;       //指針p查找插入位置
    int cnt = 0;
    while(cnt<pos)
    {
        if(p->next == NULL && cnt<pos)      //判斷插入位置是否大於鏈表長度
        {
            printf("超出鏈表長度\n");
            return;
//            exit(0);
        }
        p = p->next;            //指針p一直滑動到要插入的位置
        cnt++;
    }

    Node *r = (Node *)malloc(sizeof(Node));     //爲插入節點申請空間
    r->data = data;
    r->next = p->next;              //插入鏈表對應位置
    p->next = r;
}

//刪除鏈表中的一個數據爲x的節點
void deleteNode(LinkedList L)
{

    ElemType data;
    printf("輸出要刪除的數據: ");
    scanf("%d",&data);
    LinkedList p = L;     //p節點進行查找
    LinkedList r = L->next;     //r表示p節點後的一個節點
    if(L->next==NULL)           //判斷鏈表是否爲空
    {
        printf("鏈表爲空!\n");
        return;
//        exit(0);
    }
    while(r->next!=NULL)            //找到要刪除數據的位置
    {
        if(r->data == data) break;
        p = p->next;
        r = r->next;

    }
    if(r->data != data)         //判斷鏈表中是否存在要刪除的數據
    {
        printf("鏈表中未找到要刪除的數據!\n");
//        exit(0);
        return;
    }
    p->next = r->next;          //刪除操作
    free(r);                //釋放刪除節點的內存
}



//將鏈表各個節點的數據打印出來
void printList(LinkedList L)
{
    LinkedList p;
    if(L->next==NULL) {             //判斷鏈表是否爲空
        printf("鏈表爲空!\n");
        return;
    }
    p = L->next;

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

    printf("%d\n",p->data);
}

void reverseList(LinkedList L)
{
    if(L==NULL)              //判斷鏈表是否爲空
    {
        printf("鏈表爲空!\n");
        return;
    }
    if(L->next==NULL)                //只有一個節點時,反轉即本身,無需反轉
    {
        printf("只有一個元素,不需反轉\n");
        return;
    }
    LinkedList p, q, r;

    p = L;
    q = L->next;
    r = q->next;
    q->next=NULL;           //第一次循環時,將q->next(即反轉後的尾節點)指向null
    p = q;
    q = r;
    while(q!=NULL)
    {
        r = q->next;
        q->next = p;
        p = q;
        q = r;
    }
    L->next = p;
}



int main()
{
    LinkedList L;
    int option;
    printf("輸入要進行的操作\n");
    printf("-----------------\n");
    printf("1 頭插法創建鏈表\n");
    printf("2 尾插法插法創建鏈表\n");
    printf("3 插入節點\n");
    printf("4 刪除節點\n");
    printf("5 反轉鏈表\n");
    printf("0 退出\n");
    while(scanf("%d",&option)&&option!=0)       //輸入指令
    {
        switch (option)
        {
        case 1:
            L = createH();         //頭插法創建鏈表
            printList(L);          //打印鏈表
            break;
        case 2:
            createT();              //尾插法創建鏈表
            printList(L);          //打印鏈表
            break;
        case 3:
            insertNode(L);         //插入節點
            printList(L);          //打印鏈表
            break;
        case 4:
            deleteNode(L);         //刪除節點
            printList(L);          //打印鏈表
            break;
        case 5:
            reverseList(L);        //反轉鏈表
            printList(L);           //打印鏈表
        }
         printf("輸入要進行的操作: ");
    }
    return 0;

}








在這裏插入圖片描述

代碼參考於https://www.cnblogs.com/newwy/archive/2010/10/10/1847456.html

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