03-15复习链表知识

链表的定义

struct ListNode
{
	int val;
	ListNode *next;
	ListNode():val(0),next(nullptr);
	ListNode(int x):val(x),next(nullptr);
}

1.链表的初始化

ListNode * head=new ListNode(5);//创建1个头结点:val值为5

2.构建链表类

class Mylist
{
	struct ListNode
	{
		int val;
		ListNode *next;
		ListNode():val(0),next(nullptr);
		ListNode(int x):val(x),next(nullptr);
	};
	Mylist()
	{
	// 构造一个虚拟的头结点
		dumpy_head=new ListNode(-1);
	// 链表的大小
		_size =0;
	}
	private:
	 	ListNode *dumpy_head;
	 	int _size;

3.链表的头插(先连接后面,再连接前面)

  1. 创建新节点
  2. 新节点的next 指向原本的结点
  3. 虚拟结点指向新节点
  4. 结点的个数要加1
void addAtHead(int val)
{
	ListNode *newNode =new ListNode(val);
	newNode->next=dumpy_head->next;
	dumpy_head->next =newNode;
	_size ++;
}

4.链表的尾插: 结点的个数要加1

 void addAtTail(int val) {
 	ListNode * cur=dumpy_head->next;
 	while(cur->next !=nullptr)
 	{
 		cur=cur->next;
 	}
 	ListNode *newNode =new ListNode(val);
 	cur->next =newNode;
 	_size ++;

5.链表的反转:给定一个链表1-2-3-4-5,要求在原链表的基础上反转链表。
链表的反转
这类题目最好的方法是画图:
双指针的方法:
给定前驱指针(prev),当前指针(cur),需要反转的下一个指针tmp=cur->next(否则反转之后的话就找不到下一个结点了)

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
    ListNode* prev =nullptr;
    ListNode* cur=head;
    while(cur!=nullptr)
    {
    	// 保存下一个需要翻转的结点
    	ListNode *tmp=cur->next;
    	// 当前结点的下一个结点指向前驱结点
    	cur->next =prev;
    	// prev和cur依次向后移动
    	prev =cur;
    	cur =tmp;
    }
    return head;
 }    	

6.链表的相交 链表的相交
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null

思路:也是比较简单的,感觉是个数学问题呀。注意点:比较的链表的地址,而不是里面的val值哦!
链表的长度相等的时候:定义两个指针分别指向a和b,指针不断的向前移动,每移动一次就比较两者的地址是否相等,而如果长度不相等的话:走的总长度是一样的:(都是9步)
对于a来说:4->1->8->4->5->null->5->0->1
对于b来说:5->0->1->8->4->5->null->4->1
在这里插入图片描述
代码如下:

ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) 
{
	ListNode *a = headA;
    ListNode *b = headB;
    while(a!=b)
    {
    // a不为空的时候:一直向前移动
    	if(a!=nullptr)
    		a=a->next;
    	else
    		a=headB;
    	if(b!=nullptr)
    		b=b->next;
    	else
    		b=HeadA;
    }
    // 简洁一点的代码:
    while(a!=b)
    {
    	a!=nullptr?a=a->next:a=headB;
     	b!=nullptr?b=b->next:b=headA;
    }
    return a;
}

测试代码:
list.h

struct ListNode
{
	int val;
	ListNode* next;
	//构造函数有3种形式
	ListNode(int val) :val(val), next(nullptr){}
};
class MyLinkedList {
public:
	//构造函数,构造空链表
	MyLinkedList() {
		//创建头结点
		head = new ListNode(0);
		_size = 0;
	}
	int get(int index);
	void addAtHead(int val);
	void addAtTail(int val);
	void addAtIndex(int index, int val);
	void deleteAtIndex(int index);
	void showList();
private:
	ListNode* head;
	int _size;
};

list.cpp

int MyLinkedList::get(int index) {
	if (_size<index + 1 || index<0)
		return -1;
	ListNode *cur = head;
	for (int i = 0; i<index + 1; i++)
	{
		cur = cur->next;
	}
	return cur->val;
}
//先连接后面,再连接前面!顺序不能颠倒,否则将会找不到首元结点。
void MyLinkedList::addAtHead(int val) {
	ListNode* newNode = new ListNode(val);
	//首元结点和头结点断开,新节点和首元结点相连接。
	newNode->next = head->next;
	//头结点和新的结点相连接。
	head->next = newNode;
	_size++;
}
//结点的尾插`
void MyLinkedList::addAtTail(int val) {
	ListNode* newNode = new ListNode(val);
	//创建一个结点cur,指向头结点 
	ListNode* cur = head;
	//说明:当前结点不是最后一个结点,一直向后寻找,直到cur->next为空,
	//此时说明到达最后一个结点
	while (cur->next != nullptr)
	{
		cur = cur->next;
	}   
	//当前结点连接新的结点,_size+1;
	cur->next = newNode;
	_size++;
}
void MyLinkedList::showList()
{
	ListNode *cur = head; 
	while (cur->next!=nullptr)
	{
		cur = cur->next;
		cout << cur->val << " ";
	}
	cout << endl;
}
void MyLinkedList::addAtIndex(int index, int val) {
	if (index <= 0)
		addAtHead(val);
	else if(index == _size)
		addAtTail(val);
	else
	{
		ListNode * cur = head;
		ListNode *newNode = new ListNode(val);
		//找到索引值的前一个位置
		for (int i = 0; i < index; i++)
		{
			cur = cur->next;
		}
		//新节点的下一个结点就是索引处结点
		newNode->next = cur->next;
		//前一个结点的下一个结点是新节点
		cur->next = newNode;
	}
}
void MyLinkedList::deleteAtIndex(int index) {
	ListNode* cur = head;
	for (int i = 0; i < index; ++i)
	{
		cur = cur->next;
	}
	ListNode *tmp = cur->next;
	cur->next = cur->next->next;
	delete tmp;
}

main.c

#include "list.h"
int main()
{
	//因为4是一个常数,所以必须加上const
	const int& a = 4;
	MyLinkedList* list = new MyLinkedList();
	list->addAtHead(1);
	list->addAtTail(3);
	list->addAtIndex(1, 2);
	int i1=list->get(1);
	cout << i1 << endl;
	list->deleteAtIndex(1);
	int i2 = list->get(1);
	cout << "list[i]=" << i2 << endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值