前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数据结构【单链表基本操作】

数据结构【单链表基本操作】

作者头像
Sky_Mao
发布2020-07-24 10:11:47
3380
发布2020-07-24 10:11:47
举报

包含单链表的创建、遍历、反转(指针替换、递归)、排序、插入、删除

代码语言:javascript
复制
// list_2.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

using namespace std;

typedef struct  Node
{
    int nData;    //数据域
    Node* pNext;  //指针域 指向下一个与自身类型相同的节点
}*PNODE;

PNODE create_list();  //创建链表
void traverse_list(const PNODE pHead);  //遍历链表
void inversion_list(PNODE pHead); //反转链表
bool isEmpty_list(const PNODE pHead); //判断链表是否为空
PNODE inversion_list2(PNODE pHead);
void insert_list(PNODE pHead, int nPos, int nValue);
int getListLen(const PNODE pHead);
void delete_list(PNODE pHead, int nPos, int * nValue);
void sort_list(PNODE pHead);

//链表插入元素
void insert_list(PNODE pHead, int nPos, int nValue)
{
    int nListLen = getListLen(pHead);
    if (nPos < 1 || nPos > nListLen + 1)
    {
        return;
    }

    int i = 1;
    PNODE pNode = pHead->pNext;
    
    while (nullptr != pNode && i < nPos - 1)
    {
        pNode = pNode->pNext;
        ++i;
    }

    PNODE pInsertNode = (PNODE)malloc(sizeof(Node));
    pInsertNode->nData = nValue;

    PNODE pTempNode = pNode->pNext;
    pNode->pNext = pInsertNode;
    pInsertNode->pNext = pTempNode;
}

//获取链表个数
int getListLen(const PNODE pHead)
{
    int nLen = 0;
    PNODE pNode = pHead->pNext;//计算长度不算头节点
    while (nullptr != pNode)
    {
        pNode = pNode->pNext;
        ++nLen;
    }

    return nLen;
}

//删除链表元素
void delete_list(PNODE pHead, int nPos, int * nValue)
{
    if (isEmpty_list(pHead) || nPos < 1 || nPos > getListLen(pHead))
    {
        return;
    }

    int i = 1;
    PNODE pNode = pHead->pNext;

    while (nullptr != pNode && i < nPos - 1)
    {
        pNode = pNode->pNext;
        ++i;
    }

    PNODE pDeleteNode = pNode->pNext;
    *nValue = pDeleteNode->nData;

    PNODE pTempNode = pDeleteNode->pNext;

    //让链表连起来
    pNode->pNext = pTempNode;

    free(pDeleteNode);
}

//冒泡,只替换数据
void sort_list(PNODE pHead)
{
    //链表为空或者只有一个有效节点不排序
    if (isEmpty_list(pHead) || nullptr == pHead->pNext->pNext)
    {
        return;
    }

    PNODE pNode = pHead->pNext;
    for (; nullptr != pNode; pNode = pNode->pNext)
    {
        PNODE pNode2 = pNode->pNext;
        for (;nullptr != pNode2 && pNode != pNode2; pNode2 = pNode2->pNext)
        {
            if (pNode->nData > pNode2->nData)
            {
                int nValue = pNode->nData;
                pNode->nData = pNode2->nData;
                pNode2->nData = nValue;
            }
        }
    }
}

//递归反转链表
PNODE inversion_list2(PNODE pHead)
{
    if (nullptr == pHead || nullptr == pHead->pNext)
    {
        return pHead;
    }
    else
    {
        PNODE pTemp = inversion_list2(pHead->pNext);
        pHead->pNext->pNext = pHead; // 让最后一个节点指回去,这里形成了链表循环
        pHead->pNext = nullptr; //这里断开后,节点刚好反转

        return pTemp;
    }
}

int main()
{
    PNODE pHead = create_list();
    if (nullptr == pHead)
    {
        exit(-1);
    }

    sort_list(pHead);

    traverse_list(pHead);

    inversion_list(pHead);

    traverse_list(pHead);

    PNODE pTempNode = inversion_list2(pHead->pNext);
    pHead->pNext = pTempNode;
    traverse_list(pHead);

    insert_list(pHead, 6, 66);
    traverse_list(pHead);

    int nDeleteValue = 0;
    delete_list(pHead, 4, &nDeleteValue);

    cout << "删除的元素为:" << nDeleteValue << endl;
    traverse_list(pHead);
}

//创建非循环单向链表
PNODE create_list()
{
    int nNodeLen = 0;
    cout << "请输入创建链表的个数:";
    cin >> nNodeLen;

    if (0 == nNodeLen)
    {
        return nullptr;
    }

    //先创建头节点
    PNODE pHead = (PNODE)malloc(sizeof(Node));
    if (nullptr == pHead)
    {
        return nullptr;
    }
    //让头结点的指针域初始化为空
    pHead->pNext = nullptr;

    //定义临时节点,永远指向最后一个节点
    PNODE pTempNode = pHead;

    for (int i = 1; i <= nNodeLen; i++)
    {
        int nValue = 0;
        printf_s("请输入第%d个节点的值:", i);
        cin >> nValue;

        //创建新节点
        PNODE pNewNode = (PNODE)malloc(sizeof(Node));
        //判断内存是否申请成功
        if (nullptr == pNewNode)
        {
            return nullptr;
        }

        //给节点赋值
        pNewNode->nData = nValue;
        pNewNode->pNext = nullptr;

        //把新节点挂在尾结点上
        pTempNode->pNext = pNewNode;

        //让临时节点指向新的尾结点
        pTempNode = pNewNode;
    }

    return pHead;
}

//遍历链表
void traverse_list(const PNODE pHead)
{
    //先从头节点的指针域获取到首节点
    PNODE pTraverseNode = pHead->pNext;

    while (nullptr != pTraverseNode)
    {
        cout << pTraverseNode->nData;
        cout << "\t";
        //把当前节点的下一个节点地址赋值给pTraverseNode
        pTraverseNode = pTraverseNode->pNext;
    }

    cout << endl;

    return;
}

void inversion_list(PNODE pHead)
{
    if (isEmpty_list(pHead) || nullptr == pHead->pNext->pNext)
    {
        return;
    }

    PNODE pPrevtNode = pHead->pNext;
    PNODE pCurrentNode = pPrevtNode->pNext;
    pPrevtNode->pNext = nullptr;
    
    while (nullptr != pCurrentNode)
    {
        PNODE pTempNode = pCurrentNode->pNext;
        pCurrentNode->pNext = pPrevtNode;

        pPrevtNode = pCurrentNode;
        pCurrentNode = pTempNode;
    }

    pHead->pNext = pPrevtNode;

    return;
}

bool isEmpty_list(const PNODE pHead)
{
    //如果头节点的指针域指向的内容为空,那么就是空链表
    if (nullptr == pHead->pNext)
    {
        return true;
    }

    return false;
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档