1. 程式人生 > >無頭單鏈表的操作(基於前面的修改版)

無頭單鏈表的操作(基於前面的修改版)

slist.h

#pragma once

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>


typedef int DataType;
typedef struct SlistNode
{
    struct SlistNode *_next;
    DataType _data;
}SlistNode;

SlistNode* BuySlistNode(DataType data); //建立節點
void PrintSlist(SlistNode *pHead); //列印連結串列
void InitSlist(SlistNode **ppHead); //初始化連結串列 SlistNode* FindNode(SlistNode **ppHead, DataType data); //尋找節點 void PushBackSlist(SlistNode **ppHead, DataType data); //尾插 void PushFrontSlist(SlistNode **ppHead); //尾刪 void PopBackSlist(SlistNode **ppHead, DataType data); //頭插 void PopFrontSlist(SlistNode **ppHead); //頭刪
void PrevInsertPosSlist(SlistNode **ppHead, SlistNode *pos, DataType data); //任意位置插入,插在前 void TailInsertPosSlist(SlistNode **ppHead, SlistNode *pos, DataType data); //任意位置插入,插在後 void ErasePosSlist(SlistNode **ppHead, SlistNode *pos); //任意位置刪除 void DestroySlist(SlistNode **ppHead); //銷燬連結串列 int CountSlist(SlistNode *pHead); //計算連結串列的節點個數

slist.c

#include"slist.h"

SlistNode* BuySlistNode(DataType data) //建立節點
{
    SlistNode *head = (SlistNode*)malloc(sizeof(SlistNode)*sizeof(DataType));
    if (head)
    {
        head->_data = data;
        head->_next = NULL;
        return head;
    }
    return NULL;    
}

void InitSlist(SlistNode **ppHead) //初始化連結串列
{
    SlistNode *cur;
    assert(ppHead);
    cur = *ppHead;
    while (cur)
    {
        cur->_data = 0;
        cur = cur->_next;
    }
}

void PrintSlist(SlistNode *pHead) //列印連結串列
{
    while (pHead) //空連結串列也列印了
    {
        printf("%d--> ", pHead->_data);
        pHead = pHead->_next;
    }
    printf("NULL\n");
}

SlistNode* FindNode(SlistNode **ppHead, DataType data) //尋找節點
{
    SlistNode *find = NULL;
    assert(ppHead);
    find = *ppHead;
    while (find)
    {
        if (find->_data == data)
            return find;
        find = find->_next;
    }
    return NULL;
}

void PushBackSlist(SlistNode **ppHead, DataType data) //尾插
{
    SlistNode *tail = NULL;
    assert(ppHead);
    if (*ppHead == NULL) //沒有節點
    {
        *ppHead = BuySlistNode(data);
    }   
    else
    { 
        tail = *ppHead;
        while (tail->_next)//一個或多個節點
        {
            tail = tail->_next;
        }
        tail->_next = BuySlistNode(data);
    }
    }


void PushFrontSlist(SlistNode **ppHead) //尾刪
{
    SlistNode *del = NULL;
    SlistNode *prev = NULL;
    assert(ppHead);
    if (NULL == *ppHead)
        return;
    del = *ppHead;
    del = del->_next;
    while (del->_next)
    {
        prev = del;
        del = del->_next;
    }
    prev->_next = del->_next;    //prev->_next = NULL
    free(del);
}

void PopBackSlist(SlistNode **ppHead, DataType data) //頭插
{
    SlistNode *newnode = NULL;
    assert(ppHead);
    if (NULL == *ppHead)
        *ppHead = BuySlistNode(data);
    else
    {
        newnode = BuySlistNode(data);
        newnode->_next = *ppHead;
        *ppHead = newnode;
    }
}

void PopFrontSlist(SlistNode **ppHead) //頭刪
{
    assert(ppHead);
    if (NULL == *ppHead)
        printf("連結串列為空\n");
    else
        *ppHead = (*ppHead)->_next;
}

void PrevInsertPosSlist(SlistNode **ppHead, SlistNode *pos, DataType data) //任意位置插入,插在前面
{
    SlistNode *cur = NULL;
    assert(ppHead);
    assert(pos);
    if (pos == *ppHead)   //在頭部
    {
        cur = BuySlistNode(data);
        cur->_next = pos;
        *ppHead = cur;
    }
    else
    {
        cur = pos;
        pos = BuySlistNode(pos->_data);  //替換法插入
        pos->_next = cur->_next;
        cur->_next = pos;
        cur->_data = data;
    }
}

void TailInsertPosSlist(SlistNode **ppHead, SlistNode *pos, DataType data)  //插到後面
{
    SlistNode *newnode = NULL;
    assert(pos);
    assert(ppHead);
    if (NULL == *ppHead)
    {
        printf("連結串列為空\n");
    }
    else
    {
        newnode = BuySlistNode(data);
        newnode->_next = pos->_next;
        pos->_next = newnode;
    }

}

void ErasePosSlist(SlistNode **ppHead, SlistNode *pos) //任意位置刪除, 刪pos後的下一個節點
{
    SlistNode *cur = NULL;
    assert(ppHead);
    if (*ppHead == NULL)
        printf("連結串列為空\n");
    else 
    {
        if (pos == *ppHead)
        {
            *ppHead = pos->_next;
            free(pos);
        }
        else
        {
            cur = *ppHead;
            while (cur && (cur->_next != pos))
            {
                cur = cur->_next;
            }
            if(NULL == cur) //防止當前連結串列中沒有pos這個節點
            {
                printf("當前連結串列沒有pos這個節點\n");
            }
            else
            {
                cur->_next = pos->_next;
                free(pos);
            }
        }
    }   
}

void DestroySlist(SlistNode **ppHead)  //銷燬連結串列,前後指標法
{
    SlistNode *del = NULL;
    assert(ppHead);
    del = *ppHead;
    while (*ppHead)
    {
        *ppHead = (*ppHead)->_next;
        free(del);
        del = *ppHead;
    }
    free(*ppHead);
}

int CountSlist(SlistNode *pHead)  //計算連結串列的節點個數
{
    //assert(pHead);
    int count = 0;
    while (pHead)
    {
        ++count;
        pHead = pHead->_next;
    }
    return count;
}

test.c

#include"slist.h"

//測初始化,尾插,尾刪
//test1()
//{
//  SlistNode *list = NULL;
//  InitSlist(&list);
//  PrintSlist(list);
//  
//  PrintSlist(list);
//  PushBackSlist(&list, 1);
//  PushBackSlist(&list, 2);
//  PushBackSlist(&list, 3);
//  PushBackSlist(&list, 4);
//  PushBackSlist(&list, 5);
//  PushBackSlist(&list, 6);
//  /*PrintSlist(list);
//  InitSlist(&list);
//  PrintSlist(list);*/
//  
//  PushFrontSlist(&list);
//  PushFrontSlist(&list);
//  PrintSlist(list);
//}

//測試頭插,頭刪
//test2()
//{
//  SlistNode *list = NULL;
//  PopBackSlist(&list, 1);
//  //PopBackSlist(&list, 2);
//  //PopBackSlist(&list, 3);
//  //PopBackSlist(&list, 4);
//  //PopBackSlist(&list, 5);
//  //PopBackSlist(&list, 6);
//  //PopBackSlist(&list, 7);
//  PrintSlist(list);
//  
//  PopFrontSlist(&list);
//  PopFrontSlist(&list);
//  //PopFrontSlist(&list);
//  //PopFrontSlist(&list);
//  PrintSlist(list);
//}

//測試任意位置刪除和插入,銷燬,計算個數
test3()
{
    SlistNode *list = NULL; 
    SlistNode *pos = NULL;

    PushBackSlist(&list, 1);
    PushBackSlist(&list, 2);
    PushBackSlist(&list, 3);
    PushBackSlist(&list, 4);
    PushBackSlist(&list, 5);
    PushBackSlist(&list, 6);
    PrintSlist(list);

    printf("%d\n",CountSlist(list));

    /*pos = FindNode(&list, 1);*/
    //PrevInsertPosSlist(&list, pos, 8);
    //PrintSlist(list);
    //TailInsertPosSlist(&list, pos,7);
    //PrintSlist(list);
    //ErasePosSlist(&list, pos);
    //PrintSlist(list);

    //ErasePosSlist(&list, pos);
    PushFrontSlist(&list);
    PopFrontSlist(&list);

    printf("%d\n", CountSlist(list));
    PrintSlist(list);
    DestroySlist(&list);
    PrintSlist(list);
    printf("%d\n", CountSlist(list));
}

int main()
{
    //test1();
    //test2();
    test3();
    system("pause");
    return 0;
}