数据结构专题(一)

顺序表

  1. 顺序表
  2. 单链表
  3. 双向链表
  4. 循环链表
  5. 线性表的应用
  6. 线性表学习秘籍
1.顺序表

   顺序表静态分配定义

#define Maxsize 100
typedef struct{
	ElemType data[Maxsize];//顺序表的基地址
	int length;//顺序表的长度
}Sqlist;

   提高可移植性

typedef int ElemType;//给int起个别名ElemType

   顺序表的基本操作
1.初始化

bool InitList(SqList &L)
{
	L.elem = new int[Maxsize];	//为顺序表动态分配Maxsize个空间
	if(!L.elem) return false;	//分配空间失败
	L.length = 0;				//顺序表的长度为0
	return true;
}

2.创建

bool CreateList(SqList &L)
{
	int x,i = 0;
	while(x!=-1)//输入-1时结束,也可改为其他条件
	{
		if(L.length == Maxsize)
		{
			cout<<"顺序表已满!"
			return false;
		}
		cin>>x;			//输入一个数据元素
		L.elem[i++]=x;	//将数据存入第i个位置。然后i++
		L.length++;		//顺序表的长度加1
	}
	return true;
}

3.取值

bool GetElem(SqList L,int i,int &e)
{
	if(i<1||i>L.length) return false;
	e=L.elem[i-1];					//第i-1个单元存储着第i个数据
	return true;
}

4.查找

int LocateElem(SqList L,int e)
{
	for(i=0;i<L.length;i++)
		if(L.elem[i]==e) return i+1;
	return -1;						//如果没有找到就返回-1
}

5.插入

bool ListInsert_Sq(SqList &L,int i, int e)
{
	if(i<1 || i>L.length) return false;
	if(L.length==Maxsize) return false;
	for(int j=L.length-1;j>=i-1;j--)
		L.elem[j+1]=L.elem[j];	//从最后一个元素开始后移,直到第i个元素后移
	L.elem[i-1]=e;
	L.length++;
		return true;
}

6.删除

bool ListDelete_Sq(SqList &L;int i; int &e)
{
	if(i<1 || i>L.length) return false;
	e=L.elem[i-1];
	for(int j=i;j<=L.length-1;j++)
		L.elem[j-1]=L.elem[j];
	L.length--;
	return true;
}
2.单链表

   单链表的存储方式

typedef struct Lnode{
	ElemType data;
	struct Lnode *next;
}Lnode,*LinkList;

   单链表的基本操作
1.初始化

bool InitList_L(LinkList &L)	//构造一个空的单链表L
{
	L=new LNode;		//生成新节点作为头节点,用头指针L指向头节点
	if(!L)
		return false;	//生成头节点失败
	L->next=NULL;		//头节点的指针域空
	return true;
}

2.创建(创建单链表有两种方式“头插法”,“尾插法”)
2.1.头插法

void CreateList_H(LinkList &L)//头插法创建单链表
{
	int n;					//输入n个元素的值建立到头节点的单链表L
	LinkList s;				//定义一个指针变量
	L=new LNode;
	L->next=NULL;			//先建立一个带头节点的空链表
	cout<<"请输入n个元素:"<<endl;
	cin>>n;
	cout<<"请依次输入n个元素:"<<endl;
	cout<<"头插法创建单链表..."<<endl;
	while(n--)
	{
		s=new LNode;		//生成新节点s
		cin>>s->data;		//输入元素值赋值给新节点的数据域
		s->next=L->next;
		L->next=s;			//将新节点s插入头节点之后
	}
	
}

2.2.尾插法

void CreateList_R(LinkList &L)
{
	int n;
	LinkList s,r;
	L=new LNode;
	L->next=NULL;
	r=L;
	cout<<"输入元素个数n:"<<endl;
	cin>>n;
	cout<<"依次输入n个元素:"<<endl;
	cout<<"尾插法创建单链表..."<<endl;
	while(n--)
	{
		s=new LNode;
		cin>>s->data;
		s->next=NULL;
		r->next=s;
		r=s;
	}
}

3.取值

bool GetElem_L(LinkList L,int i, int &e)
{
	//在带头节点的单链表L中查找第i个元素
	//用e记录L中第i个数据元素的值
	int j;
	LinkList p;
	p=L->next;				//p指向第一个节点
	j=1;					//j为计数器
	while(j<i&&p)			//顺着链表向后扫描,直到p指向第i个元素或者p为空
	{
		p=p->next;			//指向下一个节点
		j++;				//计数器j加1
	}
	if(!p||j>i)				//i值不合法,i>n或i<=0
		return false;
	e=p->data;				//取第i个节点的数据域
	return true;
}

4.查找

bool LocateElem_L(LinkList L,int e)	//在带头节点的单链表L中查找值为e的元素
{
	LinkList p;
	p=L->next;
	while(p&&p->data!=e)	//沿着链表向后扫描,直到p为空或p所指节点数据域等于e
		p=p->next;			//p指向下一个节点
	if(!p)
		return false;		//查找失败,p为NULL
	return true;
}

5.插入

bool ListInsert_L(LinkList &L,int i,int e)
{
	//在带头节点的单链表L中第i个位置之前插入值为e的新节点
	int j;
	LinkList p,s;
	p=L;
	j=0;
	while(p&&j<i-1)				//查找第i-1个节点
	{
		p=p->next;
		j++;
	}
	if(!p||j>i-1)				//i>n+1或者i<1
		return false;
	s=new LNode;				//生成新结点
	s->data=e;					//将数据元素e放入新节点的数据域
	s->next=p->next;			//将新节点的指针域指向第i个节点
	p->next=s;					//将节点p的指针域指向节点s
	return true;
}

6.删除

bool ListDelete_L(LinkList &L,int i)
{	//在带头节点的单链表L中,删除第i个位置
	LinkList p,q;
	int j;
	p=L;
	j=0;
	while((p->next)&&(j<i-1))	//查找第i-1个节点,p指向该节点
	{
		p=p->next;
		j++;
	}
	if(!(p->next)||(j>i-1))
		return false;
	q=p->next;
	p->next=q->next;
	delete q;
	return true;
}
3.双向链表

   双向链表的储存方式

typedef struct DuLnode{
ElemType data;
struct DuLnode *prior,*next;
}DuLNode,*DuLinkList;

   双向链表的基本操作
1.初始化

bool InitList_L(DuLinkList &L)		//构造一个空的双向链表L
{
	L=new DuLNode;					//生成新节点作为头节点,用头指针L指向头节点
	if(!L)
		return false;				//生成节点失败
	L->prior=L->next=NULL;			//头节点的两个指针域置空
	return true;
}

2.创建
创建双向链表也可以用头插法或者尾插法。头插法创建的链表和输入顺序正好相反,称为逆序建表;尾插法创建的链表和输入顺序一致,称为正序建表。
2.1.头插法建双向链表

void CreateDuList_H(DuLinkList &L)
{	//输入n个元素的值,建立到头节点的单链表L
	int n;
	DuLinkList s;							//定义一个指针变量
	L=new DuLNode;							
	L->prior=L->next=NULL;					//先建立一个带头节点的空链表
	cout<<"输入元素个数n:"<<endl;
	cin>>n;
	cout<<"请依次输入n个元素:"<<endl;
	cout<<"头插法创建单链表..."<<endl;
	while(n--)
	{
		s=new DuLNode;						//生成新节点s
		cin>>s->data;						//输入元素值赋值给新节点的数据域
		if(L->next)							//如果L后面有节点,则修改其后面的节点的prior指针,
			//否则只修改后面3个指针即可
			L->next->prior=s;
		s->next=L->next;
		s->prior=L;
		L->next=s;							//将新节点s插入头节点之后
	}
}

2.2.尾插法建双向链表

bool ListInsert_L(DuLinkList &L,int i,int &e)
{
	//在带头结点的单链表L中第i个位置之前插入值为e的新节点
	int j;
	DuLinkList p,s;
	p=L;
	j=0;
	while(p&&j<i)
	{
		p=p->next;
		j++;
	}
	if(!p||j>i)		//i>n+1或者i<1
		return false;
	s=new DuLNode;		//生成新节点
	s->data=e;			//将新节点的数据域置为e
	p->prior->next=s;
	s->prior=p->prior;
	s->next=p;
	p->prior=s;
	return true;
}

3.取值和查找
双向链表的取值和查找和单链表一样
4.插入

bool ListInsert_L(DuLinkList &L,int i,int &e)//双向链表的插入
{
	//在带头节点的双线链表L中第i个位置之前插入值为e的新节点
	int j;
	DuLinkList p,s;
	p=L;
	j=0;
	while(p&&(j<i))					//查找第i个节点,p指向该节点
	{
		p=p->next;
		j++;
	}
	if(!p||(j>i))					//当i>n或i<1
		return false;
	s=new DuLNode;					//生成新结点
	s->data=e;						//将新节点的数据域置为e
	p->prior->next=s;
	s->prior=p->prior;
	s->next=p;
	p->prior=s;	
	return true;
}

5.删除

bool ListDelete_L(DuLinkList &L,int i)//双向链表的删除
{
	//在带头节点的双线链表L中,删除第i个节点
	DuLinkList p;
	int j;
	p=L;
	j=0;
	while(p&&(j<i))					//查找第i个节点,p指向该节点
	{
		p=p->next;
		j++;
	}
	if(!p||(j>i))					//当i>n或i<1时,删除位置不合理
		return false;
	if(p->next)						//如果p的后继节点存在
		p->next->prior=p->next;
	p->prior->next=p->next;
	delete p;						//释放被删除的节点空间
	return true;
}
4.循环链表

循环链表和普通链表的区别是最后一个节点的后继指向了头节点。

5.线性表的应用

1.合并有序顺序表
题目:将两个有序(非递减)顺序表La和Lb合并为一个新的有序(非递减)顺序表。

算法代码

void MergeSqlist(SqList La,SqList Lb,SqList &Lc)
{
	int i,j,k;
	i=j=k=0;
	Lc.length=La.length+Lb.length;
	Lc.elem=new int[Lc.Length];
	while(i<La.length&&j<Lb.length)
	{
		if(La.elem[i]<=Lb.elem[j])
			Lc.elem[k++]=La.elem[i++];
		else
			Lc.elem[k++]=Lb.elem[i++];
	}
	while(i<La.length)
		Lc.elem[k++]=La.elem[i++];
	while(j<Lb.length)
		Lc.elem[k++]=Lb.elem[i++];
}

完整代码

#include<bits/stdc++.h>
using namespace std;

#define Maxsize 100
typedef int ElemType;
typedef struct{
	ElemType *elem;//顺序表的基地址
	int length;//顺序表的长度
}SqList;

bool InitList(SqList &L)		//初始化
{
	L.elem = new int[Maxsize];	//为顺序表动态分配Maxsize个空间
	if(!L.elem) return false;	//分配空间失败
	L.length = 0;				//顺序表的长度为0
	return true;
}

void MergeSqlist(SqList La,SqList Lb,SqList &Lc)//顺序表合并函数
{
	int i,j,k;
	i=j=k=0;
	Lc.length=La.length+Lb.length;
	Lc.elem=new int[Lc.length];
	while(i<La.length&&j<Lb.length)
	{
		if(La.elem[i]<=Lb.elem[j])
			Lc.elem[k++]=La.elem[i++];
		else
			Lc.elem[k++]=Lb.elem[j++];
	}
	while(i<La.length)
		Lc.elem[k++]=La.elem[i++];
	while(j<Lb.length)
		Lc.elem[k++]=Lb.elem[j++];
}

void printList(SqList L)		//输出函数
{
	for(int i=0;i<L.length;i++)
		cout<<L.elem[i]<<" ";
	cout<<endl;
}

void scanfList(SqList &L)		//读入函数
{
	cout<<"请输入顺序表的长度:"<<endl;
	cin>>L.length;
	cout<<"请输入顺序表的元素:"<<endl;
	for(int i=0;i<L.length;i++)
			cin>>L.elem[i];
}
int main()
{
	SqList La;InitList(La);
	scanfList(La);
	
	SqList Lb;InitList(Lb);
	scanfList(Lb);
	
	SqList Lc;InitList(Lc);
	
	cout<<"顺序表La的元素为:"<<endl;
	printList(La);
	
	cout<<"顺序表Lb的元素为:"<<endl;
	printList(Lb);
	
	MergeSqlist(La,Lb,Lc);
	cout<<"顺序表Lc的元素为:"<<endl;
	printList(Lc);	

}

2.合并有序链表
题目:将两个有序(非递减)单链表La和Lb合并作为一个新的有序(非递减)单链表。

算法代码

void mergelinklist(LinkList La,LinkList Lb,LinkList &Lc)
{
	LinkList p,q,r;
	p=La->next;
	q=Lb->next;
	Lc=La;
	r=Lc;
	while(p&&q)
	{
		if(p->data<=q->data)
		{
			r->next=p;
			r=p;
			p=p->next;
		}
		else
		{
		r->next=q;
		r=q;
		q=q->next;
		}
	}
	r->next=p?p:q;
	delete Lb;
}

完整代码

#include<bits/stdc++.h>
using namespace std;

typedef int ElemType;
typedef struct Lnode{
	ElemType data;
	struct Lnode *next;
}LNode,*LinkList;

bool InitList_L(LinkList &L)	//构造一个空的单链表L
{
	L=new LNode;		//生成新节点作为头节点,用头指针L指向头节点
	if(!L)
		return false;	//生成头节点失败
	L->next=NULL;		//头节点的指针域空
	return true;
}

void CreateList_R(LinkList &L)
{
	int n;
	LinkList s,r;
	L=new LNode;
	L->next=NULL;
	r=L;
	cout<<"输入元素个数n:"<<endl;
	cin>>n;
	cout<<"依次输入n个元素:"<<endl;
	cout<<"尾插法创建单链表..."<<endl;
	while(n--)
	{
		s=new LNode;
		cin>>s->data;
		s->next=NULL;
		r->next=s;
		r=s;
	}
}

void mergelinklist(LinkList La,LinkList Lb,LinkList &Lc)
{
	LinkList p,q,r;
	p=La->next;
	q=Lb->next;
	Lc=La;
	r=Lc;
	while(p&&q)
	{
		if(p->data<=q->data)
		{
			r->next=p;
			r=p;
			p=p->next;
		}
		else
		{
		r->next=q;
		r=q;
		q=q->next;
		}
	}
	r->next=p?p:q;
	delete Lb;
}

void printLinkList(LinkList L) 
{
    LinkList p;
    p=L->next;
    while(p)
    {
    	cout<<p->data<<" ";
        p=p->next;
    }
    cout<<endl;
}

int main()
{
	LinkList La;InitList_L(La);
	CreateList_R(La);
	
	LinkList Lb;InitList_L(Lb);
	CreateList_R(Lb);

	cout<<"有序链表La为:";
	printLinkList(La);
	
	cout<<"有序链表Lb为:";
	printLinkList(Lb);
		
	LinkList Lc;InitList_L(Lc);
	mergelinklist(La,Lb,Lc);
	
	cout<<"有序链表Lc为:";
	printLinkList(Lc);
	return 0;
}

3.就地逆置单链表
题目:将带有头节点的单链表就地逆置,即元素的顺序逆转,而辅助空间复杂度为O(1)。

算法代码

void reverselinklist(LinkList &L)
{
	LinkList p,q;
	p=L->next;
	L->next=NULL;
	while(p)
	{
		q=p->next;
		p->next=L->next;
		L->next=p;
		p=q;
	}
}

完整代码

#include<bits/stdc++.h>
using namespace std;

typedef int ElemType;
typedef struct Lnode{
	ElemType data;
	struct Lnode *next;
}LNode,*LinkList;

bool InitList_L(LinkList &L)	//构造一个空的单链表L
{
	L=new LNode;		//生成新节点作为头节点,用头指针L指向头节点
	if(!L)
		return false;	//生成头节点失败
	L->next=NULL;		//头节点的指针域空
	return true;
}

void CreateList_R(LinkList &L)
{
	int n;
	LinkList s,r;
	L=new LNode;
	L->next=NULL;
	r=L;
	cout<<"输入元素个数n:"<<endl;
	cin>>n;
	cout<<"依次输入n个元素:"<<endl;
	cout<<"尾插法创建单链表..."<<endl;
	while(n--)
	{
		s=new LNode;
		cin>>s->data;
		s->next=NULL;
		r->next=s;
		r=s;
	}
}

void mergelinklist(LinkList La,LinkList Lb,LinkList &Lc)
{
	LinkList p,q,r;
	p=La->next;
	q=Lb->next;
	Lc=La;
	r=Lc;
	while(p&&q)
	{
		if(p->data<=q->data)
		{
			r->next=p;
			r=p;
			p=p->next;
		}
		else
		{
		r->next=q;
		r=q;
		q=q->next;
		}
	}
	r->next=p?p:q;
	delete Lb;
}

void printLinkList(LinkList L) 
{
    LinkList p;
    p=L->next;
    while(p)
    {
    	cout<<p->data<<" ";
        p=p->next;
    }
    cout<<endl;
}

void reverselinklist(LinkList &L)
{
	LinkList p,q;
	p=L->next;
	L->next=NULL;
	while(p)
	{
		q=p->next;
		p->next=L->next;
		L->next=p;
		p=q;
	}
}

int main()
{
	LinkList La;InitList_L(La);
	CreateList_R(La);
	
	LinkList Lb;InitList_L(Lb);
	CreateList_R(Lb);

	cout<<"有序链表La为:";
	printLinkList(La);
	
	cout<<"有序链表Lb为:";
	printLinkList(Lb);
		
	LinkList Lc;InitList_L(Lc);
	mergelinklist(La,Lb,Lc);
	
	cout<<"有序链表Lc为:";
	printLinkList(Lc);
	
	reverselinklist(Lc);
	cout<<"转置后有序链表Lc为:";
	printLinkList(Lc);
	return 0;
}

4.查找链表的中间节点
题目:带有头结点的单链表L,设计一个尽可能高效的算法求L的中间节点。

算法代码

LinkLsit findmiddle(LinkList L)
{
	LinkList p,q;
	p=L;
	q=L;
	while(p!=NULL&&p->next!=NULL)
	{
		p=p->next->next;
		q=q->next;
	}
	return q;
}

完整代码

#include<bits/stdc++.h>
using namespace std;

typedef int ElemType;
typedef struct Lnode{
	ElemType data;
	struct Lnode *next;
}LNode,*LinkList;

bool InitList_L(LinkList &L)	//构造一个空的单链表L
{
	L=new LNode;		//生成新节点作为头节点,用头指针L指向头节点
	if(!L)
		return false;	//生成头节点失败
	L->next=NULL;		//头节点的指针域空
	return true;
}

void CreateList_R(LinkList &L)
{
	int n;
	LinkList s,r;
	L=new LNode;
	L->next=NULL;
	r=L;
	cout<<"输入元素个数n:"<<endl;
	cin>>n;
	cout<<"依次输入n个元素:"<<endl;
	cout<<"尾插法创建单链表..."<<endl;
	while(n--)
	{
		s=new LNode;
		cin>>s->data;
		s->next=NULL;
		r->next=s;
		r=s;
	}
}

void mergelinklist(LinkList La,LinkList Lb,LinkList &Lc)
{
	LinkList p,q,r;
	p=La->next;
	q=Lb->next;
	Lc=La;
	r=Lc;
	while(p&&q)
	{
		if(p->data<=q->data)
		{
			r->next=p;
			r=p;
			p=p->next;
		}
		else
		{
		r->next=q;
		r=q;
		q=q->next;
		}
	}
	r->next=p?p:q;
	delete Lb;
}

void printLinkList(LinkList L) 
{
    LinkList p;
    p=L->next;
    while(p)
    {
    	cout<<p->data<<" ";
        p=p->next;
    }
    cout<<endl;
}

void reverselinklist(LinkList &L)
{
	LinkList p,q;
	p=L->next;
	L->next=NULL;
	while(p)
	{
		q=p->next;
		p->next=L->next;
		L->next=p;
		p=q;
	}
}
int findmiddle(LinkList L)
{
	LinkList p,q;
	p=L;
	q=L;
	while(p!=NULL&&p->next!=NULL)
	{
		p=p->next->next;
		q=q->next;
	}
	return q->data;
}

int main()
{
	LinkList La;InitList_L(La);
	CreateList_R(La);
	
	LinkList Lb;InitList_L(Lb);
	CreateList_R(Lb);

	cout<<"有序链表La为:";
	printLinkList(La);
	
	cout<<"有序链表Lb为:";
	printLinkList(Lb);
		
	LinkList Lc;InitList_L(Lc);
	mergelinklist(La,Lb,Lc);
	
	cout<<"有序链表Lc为:";
	printLinkList(Lc);

	cout<<"Lc的中间值为:";
	int mid=findmiddle(Lc);
	cout<<mid<<endl;
	return 0;
}
LinkList findk(LinkList L,int k)
{	
	LinkList p,q;
	p=L->next;
	q=L->next;
	while(p->next!=NULL)
	{
		if(--k<=0)
			q=q->next;
		p=p->next;
	}
	if(k>0)
		return NULL;
	else
		return q;
}

5.删除链表中的重复元素
算法代码

void Deleterep(LinkList &L)
{
	LinkList p,q;
	int x,n;
	int *flag=new int[n+1];
	for(int i=0;i<n+1;i++)
		flag[i]=0;
	p=L;
	while(p->next!=NULL)
	{
		x=abs(p->next->data);
		if(flag[x]==0)
		{
			flag[x]=1;
			p=p->next;
		}
		else
		{
			q=p->next;
			p->next=q->next;
			delete q;
		}
	}
	delete []flag;
}

完整代码

#include<bits/stdc++.h>
using namespace std;

typedef int ElemType;
typedef struct Lnode{
	ElemType data;
	struct Lnode *next;
}LNode,*LinkList;

bool InitList_L(LinkList &L)	//构造一个空的单链表L
{
	L=new LNode;		//生成新节点作为头节点,用头指针L指向头节点
	if(!L)
		return false;	//生成头节点失败
	L->next=NULL;		//头节点的指针域空
	return true;
}

void CreateList_R(LinkList &L)
{
	int n;
	LinkList s,r;
	L=new LNode;
	L->next=NULL;
	r=L;
	cout<<"输入元素个数n:"<<endl;
	cin>>n;
	cout<<"依次输入n个元素:"<<endl;
	cout<<"尾插法创建单链表..."<<endl;
	while(n--)
	{
		s=new LNode;
		cin>>s->data;
		s->next=NULL;
		r->next=s;
		r=s;
	}
}

void mergelinklist(LinkList La,LinkList Lb,LinkList &Lc)
{
	LinkList p,q,r;
	p=La->next;
	q=Lb->next;
	Lc=La;
	r=Lc;
	while(p&&q)
	{
		if(p->data<=q->data)
		{
			r->next=p;
			r=p;
			p=p->next;
		}
		else
		{
		r->next=q;
		r=q;
		q=q->next;
		}
	}
	r->next=p?p:q;
	delete Lb;
}

void printLinkList(LinkList L) 
{
    LinkList p;
    p=L->next;
    while(p)
    {
    	cout<<p->data<<" ";
        p=p->next;
    }
    cout<<endl;
}

void reverselinklist(LinkList &L)
{
	LinkList p,q;
	p=L->next;
	L->next=NULL;
	while(p)
	{
		q=p->next;
		p->next=L->next;
		L->next=p;
		p=q;
	}
}
int findmiddle(LinkList L)
{
	LinkList p,q;
	p=L;
	q=L;
	while(p!=NULL&&p->next!=NULL)
	{
		p=p->next->next;
		q=q->next;
	}
	return q->data;
}

void Deleterep(LinkList &L)
{
	LinkList p,q;
	int x,n;
	int *flag=new int[n+1];
	for(int i=0;i<n+1;i++)
		flag[i]=0;
	p=L;
	while(p->next!=NULL)
	{
		x=abs(p->next->data);
		if(flag[x]==0)
		{
			flag[x]=1;
			p=p->next;
		}
		else
		{
			q=p->next;
			p->next=q->next;
			delete q;
		}
	}
	delete []flag;
}

int main()
{
	LinkList La;InitList_L(La);
	CreateList_R(La);
	
	LinkList Lb;InitList_L(Lb);
	CreateList_R(Lb);

	cout<<"有序链表La为:";
	printLinkList(La);
	
	cout<<"有序链表Lb为:";
	printLinkList(Lb);
		
	LinkList Lc;InitList_L(Lc);
	mergelinklist(La,Lb,Lc);
	
	cout<<"有序链表Lc为:";
	printLinkList(Lc);
	
	Deleterep(Lc);
	cout<<"删除重复的数字的有序链表Lc为:";
	printLinkList(Lc);

	return 0;
}
6.线性表学习秘籍

1.顺序表秘籍
顺序表解题时需要注意几个问题。
1)位序和下标差1,第i个元素的下标为i-1。
2)移动元素时,特别注意先后顺序,以免覆盖。
3)交换元素、有序合并需要借助辅助空间。

2.链表解题秘籍
链表解题时需要注意几个问题。
1)赋值语句两端的含义。
2)修改指针顺序。
3)建立链表的两种方法:头插法、尾插法。头插法是逆序建表,尾插法是正序建表。
4)链表逆置、归并不需要额外空间,属于就地操作。
5)快慢指针法:快慢指针可以解决很多问题,如链表中间节点、倒数第k个节点、判断链表是否有环、环的起点、公共部分起点等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小成不秃头

谢谢啦

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值