数据结构——单链表

代码


#include <iostream>
using namespace std;
#include<time.h>
#include<stdlib.h>

//节点类型
struct Node
{
	Node(int data = 0) 
	{
		this->data_ = data;
		this->next_ = nullptr;
	}
	int data_;
	Node* next_;
};

//单链表代码实现
class Clink
{
public:
	Clink()
	{
		//给 head 初始化指向头结点
		this->head_ = new Node();//调用构造函数
	}
	~Clink()
	{
		//节点的释放
		Node* p = head_;
		while (p != nullptr)
		{
			head_ = head_->next_;
			delete p;
			p = head_;
		}
		head_ = nullptr;
	}
public:
	//尾插  O(n)
	void insertTail(int val)
	{
		//先找到当前链表的末尾节点
		Node* p = head_;//p指向头结点
		while (p->next_ != nullptr)
		{
			p = p->next_;
		}
		//生成新节点
		Node* node = new Node(val);
		//设置原来尾节点的地址域
		p->next_ = node;
	}
	//头插法 O(1)
	void insertHead(int val)
	{
		//生成新节点
		Node* node = new Node(val);
		//新节点设置地址域
		node->next_ = head_->next_;
		//头结点设置地址域 
		head_->next_ = node;
	}
	//链表打印
	void show()
	{
		Node* p = head_->next_;//p指向第一个节点
		while (p != nullptr)
		{
			cout << p->data_ << " ";
			p = p->next_; 
		}
		cout << endl;
	}
	//链表节点的删除——按值一个
	void remove(int val)
	{
		Node* q = head_;
		Node* p = head_->next_;
		while (p != nullptr)
		{
			if (p->data_ == val) 
			{
				q->next_ = p->next_;
				delete p;
				return;
			}
			else
			{
				q = q->next_;
				p = p->next_;
			}
		}
	}
	//链表节点的删除——按值多个
	void removeAll(int val)
	{
		Node* q = head_;
		Node* p = head_->next_;
		while (p != nullptr)
		{
			if (p->data_ == val)
			{
				q->next_ = p->next_;
				delete p;//释放开辟的堆内存			
				p = q->next_;//对指针p进行重置
			}
			else
			{
				p = p->next_;
				q = q->next_;
			}
		}
	}
	//搜索 list  O(n)
	bool find(int val)
	{
		Node* p = head_->next_;
		while (p != nullptr)
		{
			if (p->data_ == val)
			{
				return true;
			}
			p = p->next_;
		}
		return false;
	}

private:
	Node* head_;//指向链表的头结点
	Node* tail_;//指向链表的尾节点
};

int main()
{
	Clink link;
	srand(time(0));
	for (int i = 0; i < 10; i++)
	{
		int val = rand() % 100;
		link.insertTail(val);
		cout << val << " ";
	}
	cout << endl;
	link.insertTail(23);
	link.insertHead(23);
	link.insertHead(23);

	link.show();
	link.removeAll(23);
	link.show();

}

单链表逆序


//单链表逆序
void reverseLink(Clink& link)
{
	Node* head = link.head_;
	Node* p = head->next_;
	if (p == nullptr)
	{
		return;
	}
	head->next_ = nullptr;
	while (p != nullptr)
	{
		Node* q = p->next_;//记录p的下一个元素位置
		
		p->next_ = head->next_;//p的指针域
		head->next_ = p;//头结点的指针域

		p = q;
	}
}

单链表倒数第k个节点


//单链表倒数第k个节点
bool getLastKNode(Clink&link,int k,int&val)
{
	Node* p = link.head_;
	Node* q = link.head_;
	if (k < 1)//有效性判断
	{
		return false;
	}
	for (int i = 0; i < k; i++)
	{
		p = p->next_;//走到第1/2/3/4个节点
		if (p == nullptr)
		{
			return false;
		}
	}
	while (p != nullptr)
	{
		p = p->next_;
		q = q->next_;
	}
	val = q->data_;
	return true;

}
int main()
{
	Clink link;
	srand((unsigned int)time(0));
	for (int i = 0; i < 10; i++)
	{
		int val = rand() % 100;
		link.insertHead(val);
		cout << val << " ";
	}
	cout << endl;
	link.show();

	reverseLink(link);
	link.show();
	
	int val = 0;
	int k = 5;
	if (getLastKNode(link, k, val))
	{
		cout << val << endl;
	}
	else
	{
		cout << "无" << endl;
	}
}

合并两个有序的单链表


//合并两个有序的单链表
void mergeLink(Clink& link1, Clink& link2)
{
    Node* p = link1.head_->next_;
    Node* q = link2.head_->next_;
    Node* last = link1.head_;
    link2.head_ = nullptr;

    while (p != nullptr && q != nullptr)
    {
        if (p->data_ < q->data_)
        {
            last->next_ = p;
            p = p->next_;
        }
        else
        {
            last->next_ = q;
            q = q->next_;
        }
        last = last->next_;
    }
    if (p == nullptr)
    {
        last->next_ = q;
    }
    else if (q == nullptr)
    {
        last->next_ = p;
    }
}

int main()
{
    int arr[] = { 25,37,52,78,88,92,102 };
    int brr[] = { 13,23,40,56,89,100 };
    Clink link1;
    Clink link2;
    for (int v : arr)
    {
        link1.insertTail(v);
    }
    for (int v : brr)
    {
        link2.insertTail(v);
    }
    link1.show();
    link2.show();
    mergeLink(link1, link2);
    link1.show();
};

单链表判断是否有环?求环的入口节点


//单链表判断是否有环?求环的入口节点————快慢指针
bool isLinkHasCircle(Node*head,int &val)
{
    Node* fast = head;
    Node* slow = head;

    while (fast != nullptr && fast->next_ != nullptr)
    {
        slow = slow->next_;
        fast = fast->next_->next_;
        if (slow == fast)
        {
            fast = head;
            while (fast != slow)
            {
                slow = slow->next_;
                fast = fast->next_;
            }
            val = slow->data_;
            //快慢指针再次遇见,链表存在环
            return true;
        }
    }
    return false;
}

int main()
{
    Node head;
    Node n1(25), n2(67), n3(32), n4(18);
    head.next_ = &n1;
    n1.next_ = &n2;
    n2.next_ = &n3;
    n3.next_ = &n4;
    n4.next_ = &n4;
    int val = 0;
    if (isLinkHasCircle(&head, val))
    {
        cout << val << endl;
    }
    else
    {
        cout << "无" << endl;
    }
};

判断两个单链表是否相交,如果相交,返回相交节点的值


//判断两个单链表是否相交,如果相交,返回相交节点的值
bool isLinkHasMerge(Node* head1, Node* head2, int& val)
{
    int len1 = 0, len2 = 0;

    Node* p = head1;
    Node* q = head2;
    while (p != nullptr)
    { 
        len1++;
        p = p->next_;
    }
    while (q != nullptr)
    {
        len2++;
        q = q->next_;
    }

    p = head1, q = head2;
    if (len1 > len2)
    {
        int ans = len1 - len2;
        for (int i = 0; i < ans; i++)
        {
            p = p->next_;
        }
    }
    else
    {
        int ans = len2 - len1;
        for (int i = 0; i < ans; i++)
        {
            q = q->next_;
        }
    }

    while (p != nullptr)
    {
        if (p == q)
        {
            val = p->data_;
            return true;
        }
        p = p->next_;
        q = q->next_;
    }
    return false;
}


int main()
{
    Node head1;
    Node n1(25), n2(67), n3(32), n4(18);
    head1.next_ = &n1;
    n1.next_ = &n2;
    n2.next_ = &n3;
    n3.next_ = &n4;
   
    Node head2;
    Node n5(35);
    head2.next_ = &n5;
    n5.next_ = &n3;
    n3.next_ = &n4;

    int val = 0;
    if (isLinkHasMerge(&head1,&head2,val))
    {
        cout << val << endl;
    }
    else
    {
        cout << "无" << endl;
    }
    return 0;
};

删除链表倒数第k个节点


bool removeLastKNode(Node* head, int k) {
    Node* p = head;
    Node* q = head;

    if (head == nullptr || k < 1) {
        return false;
    }
    for (int i = 0; i < k; i++) {
        p = p->next_;
        if (p == nullptr) {
            return false;
        }
    }
    while (p->next_ != nullptr) {
        p = p->next_;
        q = q->next_;
    }

    Node* temp = q->next_;
    q->next_ = q->next_->next_;
    return true;
}
int main()
{
    Node head;
    Node n1(25), n2(67), n3(32), n4(18);
    head.next_ = &n1;
    n1.next_ = &n2;
    n2.next_ = &n3;
    n3.next_ = &n4;
    n4.next_ = nullptr;

    Node* p = head.next_;
    while (p != nullptr)
    {
        cout << p->data_ << " ";
        p = p->next_;
    }
    cout << endl;

    if (removeLastKNode(&head, 2))
    {
        p = head.next_;
        while (p != nullptr)
        {
            cout << p->data_ << " ";
            p = p->next_;
        }
    }

    cout << endl;
    return 0;
};

旋转链表


Node* func(Node* head, int k)
{    
    Node* p = head;

    //求链表结点的总个数
    int num = 0;
    //O(n)
    while (p->next_ != nullptr)
    {
        p = p->next_;
        num++;
    }
    num = k % (num+1);//实际移动次数
    if (num == 0)//移动次数为0的话,直接退出
    {
        return head;
    }

    //O(n)
    Node* q = head;
    p = head;
    for (int i = 0; i < num; i++)
    {
        p = p->next_;
    }
    while (p->next_!= nullptr)
    {
        p = p->next_;//倒数第一个结点
        q = q->next_;//倒数第k个结点的前一个结点
    }
    
    Node* temp = head->next_;//保存第一个节点位置
    head->next_ = q->next_;//头结点连接倒数第k个节点
    p->next_ = temp;//原来的尾节点连接原来的第一个节点
    q->next_ = nullptr;//q成为尾结点
    return head;
}
int main()
{
    Node head;
    Node n1(1), n2(2), n3(3), n4(4), n5(5);
    head.next_ = &n1;
    n1.next_ = &n2;
    n2.next_ = &n3;
    n3.next_ = &n4;
    n4.next_ = &n5;
    n5.next_ = nullptr;

    //旋转前
    Node* p = head.next_;
    while (p != nullptr)
    {
        cout << p->data_ << " ";
        p = p->next_;          
    }
    cout << endl;
   
    func(&head, 18);

    //旋转后
    p = head.next_;
    while (p != nullptr)
    {
        cout << p->data_ << " ";
        p = p->next_;
    }
    cout << endl;


    return 0;
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值