单链表示例代码

#include <iostream>
#include <cassert>

using namespace std;

//定义单链表节点
class LNode
{
public:
    LNode() : data(0), next(nullptr) {};

    int data;
    LNode *next;
};

/**
 * @brief 根据用户输入的数据创建单链表
 * @param 无
 * @return 单链表头节点的指针
 */
LNode *createList()
{
    LNode *head(nullptr);
    LNode *cur = head;
    int inputData = 0;

    cout << "Please input data: ";
    while (cin >> inputData) {
        //Create new node
        LNode *newNode = new(nothrow) LNode;
        assert(nullptr != newNode);
        newNode->data = inputData;

        //Insert new node
        if (nullptr != cur) cur->next = newNode;
        cur = newNode;
        if (nullptr == head) head = cur;
        cout << "Please input data: ";
    }
    cout << "Stop input" << endl;

    return head;
}

/**
 * @brief 获取单链表长度
 * @param head: 单链表头节点的指针
 * @return 单链表长度
 */
unsigned long getListLength(const LNode *head)
{
    unsigned long len = 0;
    for (; head; head = head->next, ++len);
    return len;
}

/**
 * @brief 打印单链表
 * @param head: 单链表头节点
 * @return 无
 */
void printList(const LNode *head)
{
    if (! head) cout << "This is a empty list." << endl;
    for (; head; head = head->next) cout << head->data << " ";
}

/**
 * @brief 释放单链表
 * @param head: 单链表头节点的指针
 * @return 无
 */
void releaseList(LNode *head)
{
    if (! head) return;

    LNode *cur = head, *nxt = head->next;
    do {
        delete cur;
        cur = nxt;
        if (nxt) nxt = cur->next;
    } while (cur);
}

/**
 * @brief 从单链表中删除指定值的节点
 * @param head: 单链表头节点的指针
 * @return 已删除节点的单链表头节点的指针
 */
LNode *delNode(LNode *head, const int nVal)
{
    if (! head) return head;

    LNode *cur = head, *pre = head;
    while (nVal != cur->data) {
        pre = cur; cur = cur->next;
        if (! cur) return head;
    }

    if (cur)
    {
        pre->next = cur->next;
        if (head == cur) head = cur->next;
        delete cur;
    }

    return head;
}

/**
 * @brief 对单链表中节点的值进行排序
 * @param head: 单链表头节点的指针
 * @return 排序完成的单链表头节点的指针
 */
LNode *sort(LNode *head)
{
    int temp = 0;
    unsigned long len = 0;
    if (!head || !head->next) return head;

    len = getListLength(head);

    for (unsigned long j = 1; j < len; ++j)
    {
        LNode *p = head;
        for (unsigned long i = 0; i < len - j; ++i)
        {
            if (p->data > p->next->data)
            {
                temp = p->data; p->data = p->next->data; p->next->data = temp;
            }
            p = p->next;
        }
    }

    return head;
}

/**
 * @brief 将单链表中节点进行逆序
 * @param head: 单链表头节点的指针
 * @return 已逆序的单链表头节点的指针
 */
LNode *reverse(LNode *head)
{
    if (!head || !head->next) return head;

    LNode *pre = nullptr;
    LNode *cur = head;
    LNode *nxt = head->next;

    while (cur)
    {
        nxt = cur->next;
        cur->next = pre;
        pre = cur;
        cur = nxt;
    }

    return pre;
}

/**
 * @brief 求单链表的中间节点
 * @param head: 单链表头节点的指针
 * @return 指向单链表中间节点的指针
 */
LNode *middleNode(LNode *head)
{
    if (!head || !head->next) return head;
    if (!head->next->next) return head;

    LNode *slow = head->next;
    LNode *fast = head->next->next;

    while(fast->next)
    {
        if (!fast->next->next) break;
        slow = slow->next;
        fast = fast->next->next;
    }

    return slow;
}

int main()
{
    LNode *head = createList();

    cout << "List: ";
    printList(head);
    cout << endl;
    cout << "Length of list is " << getListLength(head) << endl;

    cout << "Reverse list: ";
    head = reverse(head);
    printList(head);
    cout << endl;

    cout << "Sort list: ";
    sort(head);
    printList(head);
    cout << endl;

    cout << "Middle node: " << middleNode(head)->data << endl;

    int nVal = 3;
    cout << "Delete node: " << nVal << endl;
    head = delNode(head, nVal);

    cout << "List: ";
    printList(head);
    cout << endl;

    releaseList(head);

    return 0;
}

程序运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值