单链表常见题型

逆序打印单项链表

  • 循环遍历(时间复杂度o(n2))
void ReversePrint_1()
	{
		Node<DataType>* cur = _head, * tail = nullptr;
		if (_head == nullptr)
			return;
		if (_head->_next == nullptr)
			cout << _head->_data << endl;
		while (cur != tail)
		{
			while (cur->_next != tail)
				cur = cur->_next;
			cout << cur->_data << "->";
			tail = cur;
			cur = _head;
		}
		cout << "nullptr" << endl;
	}

在这里插入图片描述

  • 递归
void ReversePrint_2(Node<DataType>* _head)
	{
		if (_head != nullptr)
		{
			if (_head->_next != nullptr)
				ReversePrint_2(_head->_next);
			cout << _head->_data << " ";
		}
	}
  • 利用栈先进后出性质
void ReversePrint_3()
	{
		stack<Node<DataType>*> st;
		while (_head)
		{
			st.push(_head);
			_head = _head->_next;
		}
		while (!st.empty())
		{
			cout<<(st.top())->_data<<"->";
			st.pop();
		}
		cout << "nullptr" << endl;
	}

逆置单链表

  • 三指针法
ListNode* reverseList(ListNode* head) {
        ListNode *prev = nullptr, *cur = head, *next = nullptr;
        while(cur)
        {
            next = cur->next;
            cur->next = prev;
            prev = cur;
            cur = next;
        }
        return prev;
    }
  • 头插法(建议)
ListNode* reverseList(ListNode* head) {
        ListNode* newhead = nullptr, *cur = head;
        while(cur)
        {
            cur = head->next;
            head->next = newhead;
            newhead = head;
            head = cur;
        }
        return newhead;
    }

在这里插入图片描述

链表中间节点

Node<DataType>* FindMidNode()
	{
		Node<DataType> *slow = _head;
		while (_head && _head->_next)
		{
			_head = _head->_next->_next;
			slow = slow->_next;
		}
		return slow;
	}

链表倒数第K个节点

Node<DataType>* ListBottomKNode(int k)
	{
		Node<DataType>* node = _head;
		while (_head)
		{
			if (k--)
				node = node->_next;
			_head = _head->_next;
		}
		return node;
	}

冒泡排序

void BubbleSort()
	{
		if (_head == nullptr || _head->_next == nullptr)
			return;
		for (Node<DataType>* cur = _head; cur != nullptr; cur = cur->_next)
		{
			for (Node<DataType>* tail = cur->_next; tail != nullptr; tail = tail->_next)
			{
				if (cur->_data > cur->_next->_data)
				{
					//交换
					DataType tmp = cur->_data;
					cur->_data = cur->_next->_data;
					cur->_next->_data = tmp;
				}
			}
		}
	}

删除中间节点(只给出此节点)

void deleteNode(ListNode* node)
	 {
        node->val = node->next->val;
        node->next = node->next->next;
    }

合并俩个单链表

//非递归
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        if(l1 == nullptr || l1 == l2)
             return l2;
        if(l2 == nullptr)
            return l1;
        ListNode* list;
        if(l1->val > l2->val)
        {
            list = l2;
            l2 = l2->next;
        }
        else
        {
            list = l1;
            l1 = l1->next;
        }
        ListNode* cur = list;
        while(l1 && l2)
        {
            if(l1->val > l2->val)
            {
                cur->next = l2;
                l2 = l2->next;
            }
            else
            {
                cur->next = l1;
                l1 = l1->next;
            }
            cur = cur->next;
        }
        if(l1 == nullptr)
            cur->next = l2;
        if(l2 == nullptr)
            cur->next = l1;
        return list;
    }
//递归
	ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        if(l1 == NULL || l1 == l2)
             return l2;
        if(l2 == NULL)
            return l1;
        ListNode* list;
        if(l1->val > l2->val)
        {
            list = l2;
            list->next = mergeTwoLists(l2->next,l1);
        }
        else
        {
            list = l1;
            list->next = mergeTwoLists(l1->next,l2);
        }
        return list;
    }

链表是否带环

//定义一快一慢指针,一旦链表有环,则必相遇
bool hasCycle(ListNode *head) {
        ListNode* fast = head;
        ListNode* slow = head;
		while (fast && fast->next)
		{
			fast = fast->next->next;
			slow = slow->next;
			if (fast == slow)
				return true;
		}
		return false;
    }

带环链表环的长度

int GetCircleLength()
	{
		int len = 0;
		int sum = 2;
		bool flag = false;
		Node<DataType>* fast = _head;
		Node<DataType>* slow = _head;
		while (fast && fast->_next)
		{
			fast = fast->_next->_next;
			slow = slow->_next;
			if (fast == slow)
			{
				flag = true;
				sum--;		
			}
			if (sum == 0)
				break;
			if (flag)
			{
				len++;
			}
		}
		return len;
	}

带环链表环的入口

	//相遇点
	Node<DataType>* CheckCycle()
	{
		Node<DataType>* fast = _head;
		Node<DataType>* slow = _head;
		while (fast && fast->_next)
		{
			fast = fast->_next->_next;
			slow = slow->_next;
			if (fast == slow)
				return fast;
		}
		return nullptr;
	}
	//头节点至入口点长度为x,入口点至相遇点长度为y,环长度为n
	//慢指针走至相遇点距离为x+y+in
	//快指针走至相遇点距离为x+y+kn
	//所以x+y+kn=2x+2y+2in
	//得x = (k-2i)n - y
	//所以一个从头节点,一个从相遇点,再次相遇时即为入口点
	Node<DataType>* GetcycleEntryNode(Node<DataType>* meet)
	{
		Node<DataType>* cur = _head;
		if (_head == nullptr)
			return nullptr;
		while (cur != meet)
		{
			cur = cur->_next;
			meet = meet->_next;
		}
		return cur;
	}



ListNode *detectCycle(ListNode *head) {
        ListNode* fast = head;
        ListNode* slow = head;
        ListNode* meet = nullptr;
        while(fast && fast->next)
        {
            fast = fast->next->next;
            slow = slow->next;
            if(fast == slow)
            {
                meet = slow;
                while(meet != head)
                {
                meet = meet->next;
                head = head->next;
                }
                return meet;   
            }
        }
        return nullptr;
    }

链表是否相交

	//若俩个链表相交,则交点后的节点比相等
	//将俩个链表分别从头往后压入俩个栈
	//判断俩个栈栈顶的元素是否相等
	//若相等且下一个元素不相等则此位置即是交点。否则继续出栈判断
	ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        stack<ListNode*> st1;
		stack<ListNode*> st2;
		ListNode* node1 = nullptr;
		ListNode* node2 = nullptr;
		while (headA)
		{
			st1.push(headA);
			headA = headA->next;
		}
		while (headB)
		{
			st2.push(headB);
			headB = headB->next;
		}
		while (!st1.empty() && !st2.empty())
		{
			node1 = st1.top();
			node2 = st2.top();
			st1.pop();
			st2.pop();
            if(st1.empty() || st2.empty())
                break;
			if (st1.top() != st2.top())
				break;
		}
		return node1 == node2 ? node1 : NULL;
    }



		ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        //建环
        if(headA == nullptr || headB == nullptr)
            return nullptr;
        ListNode* last = headB;
        while(last->next)
        {
            last = last->next;
        }
        last->next = headB;
        
        //找相遇点
        ListNode* slow = headA;
        ListNode* fast = headA;
        while(fast && fast->next)
        {
            slow = slow->next;
            fast = fast->next->next;
            if(slow == fast)
            {
                slow = headA;
                //求交点
                while(slow != fast)
                {
                    slow = slow->next;
                    fast = fast->next;
                }
                last->next = nullptr;
                return fast;
            }
        }
        last->next = nullptr;
        return nullptr;
    }

判断回文链表

bool isPalindrome(ListNode* head) {
        ListNode* fast = head;
    ListNode* slow = head;
    ListNode* prev = NULL;
    while(fast)
    {
        fast = fast->next ? fast->next->next : fast->next;
        slow = slow->next;
    }
    while(slow)
    {
        ListNode* next = slow->next;
        slow->next = prev;
        prev = slow;
        slow = next;
    }
    while(head && prev)
    {
        if(head->val != prev->val)
            return false;
        head = head->next;
        prev = prev->next;
    }
    return true;
    }
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值