数据结构之单向链表(C++语言描述)

该文件是整个源文件,包括单向链表节点的定义,各种操作函数,main()测试用例。

#include <iostream>

using namespace std;


struct ListNode     //用class时需要加public,因为public默认是private的
{
    int m_nValue;
    ListNode* m_pNext;
};

ListNode* CreateList();//新建单向链表
void deleteListMemory(ListNode** pHead);//删除链表内存
void PrintListNode(ListNode* pHead);//打印单向链表
int ListLength(ListNode* pHead);//单向链表测长
ListNode* SearchListNode1(ListNode* pHead, int pos);//查找第pos位置的节点
int SearchListNode2(ListNode* pHead, int value);//查找值为value的节点所在的位置
ListNode* InsertListNode(ListNode** pHead, int pos, int data);//在第pos个节点的后面插入新节点,
                                                             //当pos等于0时,表示在头结点前面插入新节点
ListNode* DeleteListNode1(ListNode** pHead, int pos);//指定删除第pos位置的节点,pos从1开始
ListNode* DeleteListNode2(ListNode** pHead, int value);//删除数据为value的所有节点
ListNode* ReverseList(ListNode* pHead);//翻转一个链表
ListNode* SearchMidNode(ListNode* pHead);//寻找中间节点
ListNode* InsertNodeOrderly(ListNode* pHead);//在从小到大的排序链表pHead中插入节点,节点数值从控制台输入
ListNode* InsertNodeOrderly(ListNode* pHead, ListNode* pInsertNode);//将节点从参数传入,并插入
bool HasLoopInList(ListNode* pHead,ListNode** start);//判断是否有回环,如果有,将环的开始节点保存在start中
ListNode* MergeListsOrderly(ListNode* pHead1, ListNode* pHead2);//合并有序单链表,非递归方法
ListNode* MergeListsOrderly_Recursively(ListNode* pHead1, ListNode* pHead2);//合并有序单链表,递归方法
int LastRemaining_Josephuse(unsigned int num, unsigned int kth);//约瑟夫环问题
ListNode* CreateLoopList();//新建单向循环链表,用于约瑟夫环
void PrintListFromTail_Iteratively(ListNode* pHead);//从尾部到头打印链表,非递归,迭代
void PrintListFromTail_Recursively(ListNode* pHead);//从尾部到头打印链表,递归

int main()
{
    ListNode* pHead = CreateList();
    cout << endl;

    //PrintListNode(pHead);
    //cout << endl;

    //int length = ListLength(pHead);
    //if (length != 0) cout << length << endl;

    //ListNode* result1 = SearchListNode1(pHead, 3);
    //if (result1 != NULL) cout << result1->m_nValue << endl;

    //int position = SearchListNode2(pHead, 7);
    //if (position) cout << position << endl;

    //ListNode* pNode = NULL;
    //ListNode* result2 = InsertListNode(&pHead, 3, 4);
    //if (result2 != NULL) PrintListNode(result2);
    //cout << endl;

    //ListNode* result3 = DeleteListNode1(&pHead, 3);
    //if (result3 != NULL) PrintListNode(result3);

    //ListNode* result4 = DeleteListNode2(&pHead, 3);
    //if (result4 != NULL) PrintListNode(result4);

    //ListNode* result5 = ReverseList(pHead);
    //if (result5 != NULL) PrintListNode(result5);

    //ListNode* result6 = SearchMidNode(pHead);
    //if (result6 != NULL) cout << result6->m_nValue << endl;

    //ListNode* pHead1 = new ListNode();ListNode* node1 = new ListNode();ListNode* node2 = new ListNode();
    //ListNode* node3 = new ListNode();ListNode* node4 = new ListNode();ListNode* node5 = new ListNode();
    //pHead1->m_nValue = 1;pHead1->m_pNext = node1;node1->m_nValue = 3;node1->m_pNext = node2;
    //node2->m_nValue = 4;node2->m_pNext = node3;node3->m_nValue = 6;node3->m_pNext = node4;
    //node4->m_nValue = 7;node4->m_pNext = node5;node5->m_nValue = 9;node5->m_pNext = NULL;
    //ListNode* result7 = InsertNodeOrderly(pHead);
    //if (result7 != NULL) PrintListNode(result7);
    //delete pHead, node1, node2, node3, node4, node5;
    //pHead = node1 = node2 = node3 = node4 = node5 = NULL;

    //ListNode* start = NULL;
    //bool result8 = HasLoopInList(pHead, &start);
    //if (start != NULL || result8) cout << start->m_nValue << endl;

    //ListNode* pHead2 = CreateList();
    //cout << endl;
    //ListNode* result9 = NULL;
    //result9 = MergeListsOrderly(pHead1, pHead2);
    //if (result9 != NULL) PrintListNode(result9);

    //ListNode* pHead2 = CreateList();
    //cout << endl;
    //ListNode* result10 = NULL;
    //result10 = MergeListsOrderly_Recursively(pHead1, pHead2);
    //if (result10 != NULL) PrintListNode(result10);

    //int result11 = -1;
    //result11 = LastRemaining_Josephuse(3, 0);
    //if (result11 != -1) cout << result11 << endl; 

    //ListNode* pHead = CreateLoopList();
    //if (pHead != NULL) PrintListNode(pHead);

    //PrintListFromTail_Iteratively(pHead);
    //cout << endl;
    //PrintListFromTail_Recursively(pHead);
    //cout << endl;

    deleteListMemory(&pHead);
    system("pause");
    return 0;
}

ListNode* CreateList()
{
    ListNode* pHead = NULL;
    ListNode* pNode = NULL;
    ListNode* pLastNode = NULL;

    int inputValue = 0;
    while (cin >> inputValue)
    {
        pNode = new ListNode();
        if (pNode == NULL)
        {
            cout << "申请内存失败!" << endl;
            return NULL;
        }
        pNode->m_nValue = inputValue;
        pNode->m_pNext = NULL;

        if (pHead == NULL)
        {
            pHead = pNode;
        }
        else
        {
            pLastNode->m_pNext = pNode;
        }
        pLastNode = pNode;
    }

    return pHead;
}

void deleteListMemory(ListNode** pHead)
{
    if (*pHead == NULL || pHead == NULL) return;

    ListNode* pNode = *pHead;
    ListNode* pDeleted = NULL;
    while (pNode != NULL)
    {
        pDeleted = pNode;
        pNode = pNode->m_pNext;

        delete pDeleted;
        pDeleted = NULL;
    }
    pHead = NULL;
}

void PrintListNode(ListNode* pHead)
{
    if (NULL == pHead)
    {
        cout << "The list is empty!" << endl;
        return;
    }
    ListNode* pNode = pHead;
    while (pNode != NULL)
    {
        cout << pNode->m_nValue << " ";
        pNode = pNode->m_pNext;
    }
    return;
}

int ListLength(ListNode* pHead)
{
    if (NULL == pHead)
    {
        cout << "The list is empty!" << endl;
        return 0;
    }

    int length = 0;
    ListNode* pNode = pHead;
    while (pNode != NULL)
    {
        ++length;
        pNode = pNode->m_pNext;
    }

    return length;
}

ListNode* SearchListNode1(ListNode* pHead, int pos)
{
    if (pHead == NULL || pos <= 0)
    {
        cout << "Error:invalid input!" << endl;
        return NULL;
    }

    if (1 == pos) return pHead;
    else
    {
        ListNode* pNode = pHead;
        int index = 2;
        while (index <= pos)
        {
            pNode = pNode->m_pNext;
            if (NULL == pNode)
            {
                cout << "Error:the pos is larger than the length!" << endl;
                return NULL;
            }
            ++index;
        }
        return pNode;
    }
}

int SearchListNode2(ListNode* pHead, int value)
{
    if (NULL == pHead)
    {
        cout << "Error:the list is empty!" << endl;
        return 0;
    }

    ListNode* pNode = pHead;
    int pos = 1;
    while (pNode != NULL && pNode -> m_nValue != value)
    {
        pos++;
        pNode = pNode->m_pNext;
    }

    if (NULL == pNode)
    {
        cout << "Can't find the node!" << endl;
        return 0;
    }
    else return pos;
}

ListNode* InsertListNode(ListNode** pHead, int pos, int data)
{
    if (pos < 0)
    {
        cout << "Error:the position is invalid!" << endl;
    }

    ListNode* pNew = new ListNode();
    pNew->m_nValue = data;
    pNew->m_pNext = NULL;

    if (NULL == pHead || NULL == *pHead)
    {
        *pHead = pNew;
    }
    else if (0 == pos)
    {
        pNew->m_pNext = *pHead;
        *pHead = pNew;  
    }
    else
    {
        ListNode* pNode = SearchListNode1(*pHead, pos);
        if (pNode != NULL)
        {
            pNew->m_pNext = pNode->m_pNext;
            pNode->m_pNext = pNew;
        }   
    }
    return *pHead;
}

ListNode* DeleteListNode1(ListNode** pHead, int pos)
{
    if (*pHead == NULL || pHead == NULL || pos <= 0)
    {
        cout << "List is empty or the position is invalid!" << endl;
        return *pHead;
    }

    if (pos == 1)
    {
        ListNode* pDeleted = *pHead;
        *pHead = (*pHead)->m_pNext;
        delete pDeleted;
        pDeleted = NULL;

        return *pHead;
    }
    else
    {
        ListNode* pNode = SearchListNode1(*pHead, pos - 1);
        if (pNode != NULL && pNode->m_pNext != NULL)
        {
            ListNode* pDeleted = pNode->m_pNext;
            pNode->m_pNext = pNode->m_pNext->m_pNext;

            delete pDeleted;
            pDeleted = NULL;
        }
        return *pHead;
    }
}

ListNode* DeleteListNode2(ListNode** pHead, int value)
{
    if (*pHead == NULL || pHead == NULL)
    {
        cout << "List is empty!" << endl;
        return NULL;
    }

    ListNode* pToBeDeleted = NULL;
    while ((*pHead) != NULL && (*pHead)->m_nValue == value)
    {
        pToBeDeleted = *pHead;
        *pHead = (*pHead)->m_pNext;

        delete pToBeDeleted;
        pToBeDeleted = NULL;
    }

    ListNode* pNode = *pHead;
    while (pNode != NULL && pNode->m_pNext != NULL)
    {
        while (pNode->m_pNext->m_pNext != NULL && pNode->m_pNext->m_nValue == value)
        {
            pToBeDeleted = pNode->m_pNext;
            pNode->m_pNext = pNode->m_pNext->m_pNext;

            delete pToBeDeleted;
            pToBeDeleted = NULL;
        }
        if (pNode->m_pNext->m_nValue != value)
        {
            pNode = pNode->m_pNext;
        }
        else//pNode->m_pNext->m_pNext == NULL
        {
            if (pNode->m_pNext->m_nValue == value)
            {
                pToBeDeleted = pNode->m_pNext;
                pNode->m_pNext = pNode->m_pNext->m_pNext;

                delete pToBeDeleted;
                pToBeDeleted = NULL;
            }
        }
    }
    return *pHead;
}

ListNode* ReverseList(ListNode* pHead)
{
    if (pHead == NULL)
    {
        cout << "List is empty!" << endl;
        return NULL;
    }

    if (pHead->m_pNext == NULL) return pHead;

    ListNode* pPreNode = pHead;
    ListNode* pCurNode = pHead->m_pNext;
    ListNode* pNxtNode = pCurNode->m_pNext;
    ListNode* pReverseHead = NULL;

    pPreNode->m_pNext = NULL;

    while (pNxtNode != NULL)
    {
        pCurNode->m_pNext = pPreNode;

        pPreNode = pCurNode;
        pCurNode = pNxtNode;
        pNxtNode = pCurNode->m_pNext;
    }
    pCurNode->m_pNext = pPreNode;

    pReverseHead = pCurNode;
    return pReverseHead;
}

ListNode* SearchMidNode(ListNode* pHead)
{
    if (NULL == pHead)
    {
        cout << "List is empty!" << endl;
        return NULL;
    }

    ListNode* pCurNode = pHead;
    ListNode* pMidNode = pHead;
    int curIndex = 0;
    int midIndex = 0;

    while (pCurNode != NULL)
    {
        if (curIndex / 2 > midIndex)
        {
            midIndex++;
            pMidNode = pMidNode->m_pNext;
        }
        curIndex++;
        pCurNode = pCurNode->m_pNext;
    }
    return pMidNode;
}

ListNode* InsertNodeOrderly(ListNode* pHead)
{
    int value = 0;
    while (cin >> value)
    {
        ListNode* pInsertNode = new ListNode();
        pInsertNode->m_nValue = value;
        pInsertNode->m_pNext = NULL;

        if (pHead == NULL)
        {
            pHead = pInsertNode;
            continue;
        }

        if (pInsertNode->m_nValue <= pHead->m_nValue)
        {
            pInsertNode->m_pNext = pHead;
            pHead = pInsertNode;
            continue;
        }

        ListNode* pCurNode = pHead;
        ListNode* pPreNode = NULL;
        while (pInsertNode->m_nValue > pCurNode->m_nValue && pCurNode->m_pNext != NULL)
        {
            pPreNode = pCurNode;
            pCurNode = pCurNode->m_pNext;
        }
        if (pInsertNode->m_nValue <= pCurNode->m_nValue)
        {
            pPreNode->m_pNext = pInsertNode;
            pInsertNode->m_pNext = pCurNode;
        }
        else pCurNode->m_pNext = pInsertNode;
    }
    return pHead;
}

bool HasLoopInList(ListNode* pHead, ListNode** start)
{
    if (pHead == NULL)
    {
        cout << "List is empty!" << endl;
        *start = NULL;
        return false;
    }

    ListNode* pBehind = pHead;
    ListNode* pAhead = pHead->m_pNext;
    if (pAhead == NULL)
    {
        cout << "List has only one node, has no loop!" << endl;
        *start = NULL;
        return false;
    }

    while (pAhead != NULL && pBehind != NULL)
    {
        if (pAhead == pBehind)
        {
            int nodesInLoop = 1;
            ListNode* pNode1 = pAhead;
            while (pNode1->m_pNext != pAhead)
            {
                ++nodesInLoop;
                pNode1 = pNode1->m_pNext;
            }

            pNode1 = pHead;
            for (int i = 0; i < nodesInLoop; ++i)
            {
                pNode1 = pNode1->m_pNext;
            }

            ListNode* pNode2 = pHead;
            while (pNode1 != pNode2)
            {
                pNode1 = pNode1->m_pNext;
                pNode2 = pNode2->m_pNext;
            }
            *start = pNode1;
            return true;
        }
        pBehind = pBehind->m_pNext;
        pAhead = pAhead->m_pNext;
        if (pAhead != NULL)
            pAhead = pAhead->m_pNext;
    }
    cout << "List has no loop!" << endl;
    *start = NULL;
    return false;
}

ListNode* MergeListsOrderly(ListNode* pHead1, ListNode* pHead2)
{
    if (pHead1 == NULL) return pHead2;
    else if (pHead2 == NULL) return pHead1;

    ListNode* pMergeHead = NULL;
    ListNode* pNode = NULL;
    if (ListLength(pHead1) >= ListLength(pHead2))
    {
        pMergeHead = pHead1;
        pNode = pHead2;
    }
    else
    {
        pMergeHead = pHead2;
        pNode = pHead1;
    }

    ListNode* pNxtNode = NULL;
    while (pNode != NULL)
    {
        pNxtNode = pNode->m_pNext;
        pMergeHead = InsertNodeOrderly(pMergeHead, pNode);
        pNode = pNxtNode;
    }
    if (pMergeHead == pHead1) pHead2 = NULL;
    else if (pMergeHead == pHead2) pHead1 = NULL;
    return pMergeHead;
}

ListNode* InsertNodeOrderly(ListNode* pHead, ListNode* pInsertNode)
{
    if (pHead == NULL)
    {
        pHead = pInsertNode;
        return pHead;
    }
    if (pInsertNode->m_nValue <= pHead->m_nValue)
    {
        pInsertNode->m_pNext = pHead;
        pHead = pInsertNode;
        return pHead;
    }

    ListNode* pCurNode = pHead;
    ListNode* pPreNode = NULL;
    while (pInsertNode->m_nValue > pCurNode->m_nValue && pCurNode->m_pNext != NULL)
    {
        pPreNode = pCurNode;
        pCurNode = pCurNode->m_pNext;
    }
    if (pInsertNode->m_nValue <= pCurNode->m_nValue)
    {
        pPreNode->m_pNext = pInsertNode;
        pInsertNode->m_pNext = pCurNode;
    }
    else pCurNode->m_pNext = pInsertNode;

    return pHead;
}

ListNode* MergeListsOrderly_Recursively(ListNode* pHead1, ListNode* pHead2)
{
    if (pHead1 == NULL) return pHead2;
    if (pHead2 == NULL) return pHead1;

    ListNode* pMergeHead = NULL;
    if (pHead1->m_nValue < pHead2->m_nValue)
    {
        pMergeHead = pHead1;
        pMergeHead->m_pNext = MergeListsOrderly_Recursively(pHead1->m_pNext, pHead2);
    }
    else
    {
        pMergeHead = pHead2;
        pMergeHead->m_pNext = MergeListsOrderly_Recursively(pHead1, pHead2->m_pNext);
    }
    return pMergeHead;
}

#include <list>
int LastRemaining_Josephuse(unsigned int num, unsigned int kth)
{
    if (num < 1 || kth < 1)
    {
        cout << "Error: invalid input!" << endl;
        return -1;
    }

    std::list<int> numbers;
    numbers.clear();
    for (int i = 0; i < num; ++i)
        numbers.push_back(i);

    list<int>::iterator current = numbers.begin();
    while (numbers.size() > 1)
    {
        for (int i = 1; i < kth; ++i)
        {
            current++;
            if (current == numbers.end())
                current = numbers.begin();
        }

        list<int>::iterator next = ++current;
        if (next == numbers.end())
            next = numbers.begin();

        current--;
        numbers.erase(current);
        current = next;
    }
    return (*current);
}

ListNode* CreateLoopList()
{
    ListNode* pHead = CreateList();
    if (pHead == NULL || pHead->m_pNext == NULL)
    {
        cout << "Can't create a loop list,list is empty or has only one node!" << endl;
        return NULL;
    }

    ListNode* pNode = pHead;
    while (pNode->m_pNext != NULL)
    {
        pNode = pNode->m_pNext;
    }
    pNode->m_pNext = pHead;

    return pHead;
}

#include <stack>
void PrintListFromTail_Iteratively(ListNode* pHead)
{
    if (pHead == NULL)
    {
        cout << "List is empty!" << endl;
        return;
    }

    std::stack<ListNode*> nodesStack;
    ListNode* pNode = pHead;
    while (pNode != NULL)
    {
        nodesStack.push(pNode);
        pNode = pNode->m_pNext;
    }

    while (!nodesStack.empty())
    {
        pNode = nodesStack.top();
        cout << pNode->m_nValue << " ";
        nodesStack.pop();
    }
}

void PrintListFromTail_Recursively(ListNode* pHead)
{
    if (pHead != NULL)
    {
        if (pHead->m_pNext != NULL)
        {
            PrintListFromTail_Recursively(pHead->m_pNext);
        }
        printf("%d ", pHead->m_nValue);
    }
}






  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值