单链表的基本操作(一)

单链表在插入、删除时较为方便,平时做题或者面试也会遇到很多,下面对单链表的操作做一些介绍。

本文参考了一些blog,不过只记得下面这个啦:

http://blog.csdn.net/puqutogether/article/details/39990419


定义一个结构体

struct Node
{
	int data;
	Node* next;
};
在 运算前先定义一个全局变量 head:

Node* head=NULL;


1.创建一个有头结点的链表

bool CreateLink()//创建链表
{
	head=new Node;
	if(head==NULL)
		return false;
	else
	{
		head->data=0;
		head->next=NULL;
		return true;
	}
}
2.增加节点
bool AddNode(Node *addNode)//增加节点
{
	Node *p=head->next;
	Node *q=head;

	while(p!=NULL)//往后查找,直到找到最后的位置
	{
		q=p;
		p=p->next;
	}
	q->next=addNode;
	addNode->next=NULL;
	return true;
}
3.计算节点总数

int CountNode()//计算节点
{
	Node *p=head->next;

	int count=0;
	while(p!=NULL)
	{
		count++;
		p=p->next;
	}
	return count;
}

4.查找节点

int Search(int x)//查找节点的元素值为x的下标
{
	Node *p=head->next;
	
	for(int j=1;p&&p->data!=x;j++)
		p=p->next;
	if(p)
		return j;
	return -1;
}
5.插入节点

bool Insert(int i,int x)//在a[i]节点后面插入x(节点从a[0]开始标记)
{
	Node *p=head;
	for(int j=0; j<=i; j++)
		p=p->next;

	Node *q=new Node;
	q->data=x;
	
	q->next=p->next;//在p后面插入q,无需区分头结点和一般节点
	p->next=q;

	return true;
}
6.删除节点

bool Delete(int i)//删除第i个节点
{
	Node *q=head,*p;
	for(int j=0; j<i; j++)
	{
		q=q->next;
	}

	p=q->next;
	q->next=p->next;
	delete p;
	return true;
}
7.链表反转


每次都将第一个节点之后的节点放在head后面。tmp指向第一个节点,p指向第二个节点,再把第二个节点放在head与第一个节点之间,就完成了第一次交换,顺序就变成了Head-结点2-结点1-结点3-结点4-NULL。同样下次再把结点3放在head与结点之间,以此类推。

void ReverseLink()//链表反转
{
        Node *tmp=NULL;
	Node *p=NULL;

	tmp=head->next;
	while(tmp->next!=NULL)
	{
		p=tmp->next;
		tmp->next=p->next;
		p->next=head->next;
		head->next=p;
	}
}

8.查找倒数第k个节点

给两个指针p和q,让其中一个指针p领先q指针k步,然后再同时移动p和q指针,当领先的指针p先到达链表尾部时,后面的指针q所指向的节点恰好为倒数第k个节点。

Node* GetKthNode(int k)
{
	Node *p=head;
	Node *q=head;

	while(k>1 && p->next!=NULL)
	{
		p=p->next;
		k--;
	}
	
	if(k>1 || p==NULL)
		return NULL;

	while(p->next!=NULL)
	{
		q=q->next;
		p=p->next;
	}
	return q;
}

9.判断链表是否成环

 这里使用两个指针q和p,一个指针走两步(p),一个指针走一步(q)。如果成环,两个指针会在O(n)内相遇 ,否则先走的会指向空。

bool Iscircle(Node *head)//判断是否有环
{
   Node *p=head;
   Node *q=head;

   while(p!=NULL && p->next!=NULL)
   {
	   p=p->next->next;
	   q=q->next;

	   if(p==q)
          return true;
   }
   return false;
}







  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值