无头结点单链表基本操作

动态顺序表

linklist.h
#pragma once

#include <stdio.h>
#include <assert.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>

typedef int DataType;

typedef struct ListNode
{
    struct ListNode* pNext;
    DataType _data;
}Node,*PNode;

// 链表的初始化
void SListInit(PNode* pHead);

//创建一个节点
PNode BuyListNode(DataType data);

// 尾插
void SListPushBack(PNode* pHead, DataType data);

// 尾删
void SListPopBack(PNode* pHead);

// 头插
void SListPushFront(PNode* pHead, DataType data);

// 头删
void SListPopFront(PNode* pHead);

// 在链表中查找值为data的元素,找到后返回值为data的结点
PNode SListFind(PNode pHead, DataType data);

// 在pos位置插入值为data的结点
void SListInsert(PNode* pHead, PNode pos, DataType data);

// 删除pos位置额结点
void SListErase(PNode* pHead, PNode pos);

// 计算链表长度
int SListSize(PNode pHead);

// 判断链表是否为空
int SListEmpty(PNode pHead);

// 销毁链表
void SListDestroy(PNode* pHead); 

//打印链表
void print(PNode pHead);


linklist.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "linklist.h"

//初始化
void SListInit(PNode* pHead)
{
    assert(pHead);        //因为pHead是外部实参的地址,外部已经定义,所以地址是一定存在的,不可能为空
                          //如果为NULL的话一定是出错误了,所以用assert断言来提示
    *pHead = NULL;
}

//尾插
void SListPushBack(PNode* pHead, DataType data)
{
    assert(pHead);
    if(*pHead == NULL)
        *pHead = BuyListNode(data);
    else 
    {
        PNode pCur = *pHead;
#if 1
        while(pCur->pNext)        //当本节点的pNext为空是跳出,直接让pCur->pNext指向要插入数据的节点
            pCur = pCur->pNext;    
#else
        PNode pPre = NULL;
        while(pCur)
        {
            pPre = pCur;
            pCur = pCur->pNext;  //这是不行的,因为pCur最后一定指向空才跳出
                               //如果为空的话,在下一条语句pCur->pNext就会出错
        }
        pCur = pPre;
#endif
        pCur->pNext = BuyListNode(data);  //走到这一步pCur->pNext一定为空要插入节点,应该让pCur->pNext指向新节点
    }
}

//尾删
void SListPopBack(PNode* pHead)
{
    //三种情况1、0个 2、1个 3、多个
    PNode pCur = *pHead;  
    PNode pPre = NULL;
     assert(pHead);
    if(*pHead == NULL)
    {
        printf("无节点可删!\n");
        return;
    }
    else if((*pHead)->pNext == NULL)
    {
        free(*pHead);
        *pHead = NULL;
        return;
    }
    while(pCur->pNext != NULL)
    {
        pPre = pCur;
        pCur = pCur->pNext;
    }
    free(pCur); 
    pPre->pNext = NULL;
}


//头插
void SListPushFront(PNode* pHead, DataType data)
{
    PNode pCur;
    assert(pHead);
    if(*pHead == NULL)
    {
        *pHead = BuyListNode(data);
    } 
    else 
        pCur = BuyListNode(data);
    pCur->pNext = *pHead;
    *pHead = pCur;
}

//头删
void SListPopFront(PNode* pHead)
{
    PNode next;
    assert(pHead);
    if(*pHead == NULL)
    {
        printf("无数据可删!\n");
        return;
    }
    else
    {
        next = (*pHead)->pNext;
        free(*pHead);
        *pHead = next;
    }
}

//查找
PNode SListFind(PNode pHead, DataType data)
{
    if(pHead == NULL)
        return NULL;
    while(pHead)
    {
        if(pHead->_data == data)
            return pHead;
        pHead = pHead->pNext;
    }
    return NULL;
}

// 在pos位置插入值为data的结点
void SListInsert(PNode* pHead, PNode pos, DataType data)
{
    assert(pHead);
    if(*pHead == NULL || pos == NULL)
        return ;
    if(*pHead == pos)
    {
        PNode pCur =BuyListNode(data);
        pCur->pNext = *pHead;
        *pHead = pCur;
    }
    else
    {
        PNode pCur = *pHead;
        PNode pPre = NULL;
        while( pCur != pos && pCur )
        {
            pPre = pCur;
            pCur = pCur->pNext;
        }
        if(pCur)
        {
            PNode pNew = BuyListNode(data);
            pNew->pNext = pCur;
            pPre->pNext = pNew;
        }
    }
}

// 删除pos位置额结点
void SListErase(PNode* pHead, PNode pos)
{
    assert(pHead);
    if(*pHead == NULL || pos == NULL)
        return;
    else  if(pos == *pHead)
    {
        PNode  pDel = *pHead;
        *pHead = (*pHead)->pNext;
        free(pDel);
    }
    else
    {
        PNode pCur = *pHead;
        PNode pPre = NULL;
        while(pCur!=pos && pCur)
        {
            pPre = pCur;
            pCur = pCur->pNext;
        }
        if(pCur)
        {
            pPre->pNext = pCur->pNext;
            free(pCur);
        }
    }
}

//计算链表长度
int SListSize(PNode pHead)
{
    int count = 0;
    if(pHead == NULL)
        return 0;
    else
    {
        while(pHead)
        {
            count++;
            pHead = pHead->pNext;
        }
    }
    return count;

}
//判断为空
int SListEmpty(PNode pHead)
{
    return pHead?1:0;
    //if(pHead == NULL)
    //{
    //  printf("链表为空!\n");
    //  return 0;
    //}
    //else 
    //  printf("链表不为空!\n");
    //return 0;
}

//清空链表
void SListDestroy(PNode* pHead)
{
    PNode pCur = *pHead;
    PNode pNext = NULL;
    assert(pHead);
    if(*pHead == NULL)
            return;
    else
    {
        *pHead = NULL;
        while(pCur)
        {
            pNext = pCur->pNext;
            free(pCur);
            pCur = pNext;
        }
    }
}

//创建一个节点
PNode BuyListNode(DataType data)
{
    PNode pNewNode = (PNode)malloc(sizeof(Node));
    if(pNewNode == NULL)
    {
        assert(0);
        return NULL;
    }
    pNewNode->_data = data;
    pNewNode->pNext = NULL;
    return pNewNode;
}

//打印链表
void print(PNode pHead)
{
    if(pHead == NULL)
    {
        printf("NULL\n");
        return;
    }
    while(pHead)   
    {
        printf("%d->",pHead->_data);
        pHead = pHead->pNext;
    }
    printf("NULL\n");
}


test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "linklist.h"
void test();
void test1();

int main()
{
    test();
    return 0;
}

//测试
//查找、任意插、任意删、判空、销毁
void test1()
{
    PNode pHead = NULL;        
    SListInit(&pHead);         //初始化
    SListPushBack(&pHead,54);  //尾插
    SListPushBack(&pHead,465);
    SListPushBack(&pHead,8);
    SListPushBack(&pHead,78);

    printf("%p\n",SListFind(pHead,465));        //打印465的节点(465的存储地址)
    printf("%d\n",SListFind(pHead,465)->_data); //打印465的节点的内容

    SListInsert(&pHead,SListFind(pHead,54),100);//在54的位置插入一个数据100
    print(pHead);

    SListErase(&pHead,SListFind(pHead,100));    //删除链表中数据为100的节点
    print(pHead);

    printf("节点的个数为:%d\n",SListSize(pHead)); //打印节点的个数

    printf("%d\n",SListEmpty(pHead));             //判断链表是否为空打印1不为空0为空

    SListDestroy(&pHead);                           //销毁链表
    print(pHead);
}
//测试
//头删、头插、尾删、尾插
void test()
{
    PNode pHead = NULL;        //这里直接赋值为空
    SListInit(&pHead);         //初始化
    SListPushBack(&pHead,3);   //尾插
    SListPushBack(&pHead,4);   //尾插
    print(pHead);

    SListPushFront(&pHead,6);  //头插
    SListPushFront(&pHead,34);
    SListPushFront(&pHead,54);
    print(pHead);

    SListPopBack(&pHead);       //尾删
    SListPopFront(&pHead);      //头删

    print(pHead);
    SListDestroy(&pHead); 
}


你可能感兴趣的:(c语言,数据结构)