链表(初步)

一,创建一个单向链表

引入:情景就是我要存下一大批玩家的数据信息,没有一整块,或者难以找到一整块儿的存储空间,那用链表的话(核心在于一个包含数据域和指针域的结构体,数据域存储玩家信息,指针域存储放下一个玩家的内存的首地址),就相当于把碎片化的内存联系起来达到整体的,连续的效果。

当然,进一步就会强调,头(头指针,存储第一个玩家的首地址),尾(尾节点,尾指针是NULL,什么地方也不指向)。

1,简易版

/*创建一个单向链表1.0*/
#include<stdio.h>
#include<stdlib.h>
/*准备工作,包含数据域和指针域的结构体*/
typedef struct player
{
    int account;
    char name[20];
    int HP;
    int power;
    int intelligence;
    struct player *next;
}PLAYER;
int main()
{
    /*一,创建节点*/
    PLAYER pl1={1001,"狗兔秃",27778,36669,666};
    PLAYER pl2={1002,"富贵儿",999999,666666,888};
    PLAYER pl3={1002,"修勾儿",333222,33323,555};
    /*二,连接,给指针与赋上后继节点的地址值*/
    pl1.next=&pl2;
    pl2.next=&pl3;
    /*三,确定头指针*/
    PLAYER *head=&pl1;/*头指针类型要和节点里的一致*/
    /*四,确定尾节点*/
    pl3.next=NULL;
    /*实际操作*/
    printf("%s\n",pl2.name);
    printf("%d\n",pl1.account);
    printf("%d\n",pl3.power);
    return 0;
}

2.简易版(节点极少)+模块化

?:为什么模块化之后要用malloc申请内存

--:因为模块化之后仍然用结构体变量的话,它就变成了局部变量,它随着函数的使用而开始,随着函数的结束而结束,由栈来存储,系统会自动产生和回收这部分内存,也就是说运行完这个函数,里边定义的那些变量就没了。因此,模块化之后,我们用指向结构体变量的指针来操作,给它用malloc申请内存(堆里面的),就不会产生以上的后果,反而得到我们真实想要的效果。

/*创建一个单向链表2.0*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/*准备工作,包含数据域和指针域的结构体*/
typedef struct player
{
	int account;
	char name[20];
	int HP;
	int power;
	int intelligence;
	struct player *next;
}PLAYER;
PLAYER * Build(void);
int main()
{
	PLAYER * head;
	head=Build();
	/*实际操作*/
	printf("The first player's name is: %s\n",head->name);
	return 0;
}
PLAYER * Build(void)
{
	/*一,创建节点*/
	PLAYER *pl1 = (PLAYER *)malloc(sizeof(PLAYER));
	PLAYER *pl2 = (PLAYER *)malloc(sizeof(PLAYER));
	PLAYER *pl3 = (PLAYER *)malloc(sizeof(PLAYER));
	if(pl1!=NULL)
	{
	pl1->account=1001;
	strcpy(pl1->name,"狗兔秃");
	pl1->HP=27778;
	pl1->power=36669;
	pl1->intelligence=666;
	}
	if(pl2!=NULL)
	{
	pl2->account=1002;
	strcpy(pl2->name,"富贵儿");
	pl2->HP=999999;
	pl2->power=666666;
	pl2->intelligence=888;
	}
	if(pl3!=NULL)
	{
	pl3->account=1003;
	strcpy(pl3->name,"修勾儿");
	pl3->HP=333222;
	pl3->power=33323;
	pl3->intelligence=555;	
	}
	/*二,连接,给指针与赋上后继节点的地址值*/
	pl1->next=pl2;
	pl2->next=pl3;
	/*三,确定头指针*/
	PLAYER *head=pl1;/*头指针类型要和节点里的一致*/
	/*四,确定尾节点*/
	pl3->next=NULL;
	/*最后返回头指针*/
	return head;
}

3.复杂一点点+模块化

注:Build这个函数,把节点分成头节点和其他节点进行写入。

malloc申请完内存之后,首先应该判断是否申请到了,也就是malloc是有可能申请不到内存的。

申请到了可以继续操作,没申请到就exit(0)结束函数。

首先我们要定义三个指向结构体的指针变量,head不用说,存放头指针的,最后要作为返回值。

Pt则是我们每次要读入数据的结点的指针,应该指向他们各自的‘首地址’。

prePt的话则是作为一个中介,或者说推进的存在,它总是用来保存链表当前的结点的地址,所以十分重要。

然后先单独给头节点(没有前驱节点)申请内存,头节点申请到了才可以继续下去,然后给头节点读入数据,

对下面操作的准备工作:

(用Pt)给head赋值<=>确定头指针,(用当前Pt)给prePt赋值才能往后推进<=>定下头节点这个格子。

接下来,进入循环,给下一个节点申请内存,判断是否申请成功,

关键理解这一部分的赋值,将新申请的Pt赋给prePt->next(当前的结点的的指针域)<=>填满上一个格子的指针域,再将当前Pt(地址)整体赋给prePt<=>定下一个格子。

最后就是对尾节点的处理了,在循环外,把NULL赋值给Pt->next,作为当前节点(尾节点)的地址,当然赋给prePt也是等价的

总的来说,最关键的是对赋值操作的理解,赋值操作(抽象化地)分为两类,定格子,以及顶格子里的内容(数据域不在这里说,由键盘输入;指针域,装的是下一个格子的地址,也就是只有走到下一步才能定下上一个格子的指针域这块内容)。还是画图理解吧,比较保险。

/*创建一个单向链表3.0*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/*准备工作,包含数据域和指针域的结构体*/
typedef struct player
{
	int account;
	char name[20];
	int HP;
	int power;
	int intelligence;
	struct player *next;
}PLAYER;
PLAYER *Build(int num);
int main()
{
	int n;
	/*打算要多少个节点*/
	scanf("%d",&n);
	PLAYER * head;
	head=Build(n);
	/*实际操作*/
	printf("The first player's name is: %s\n",head->name);
	return 0;
}
PLAYER * Build(int num)
{
	/*一,创建节点*/
	/*二,连接,给指针与赋上后继节点的地址值*/
	/*三,确定头指针*/
	/*头指针类型要和节点里的一致*/
	/*四,确定尾节点*/
	/*最后返回头指针*/
	PLAYER *Pt,*prePt,*head;
	int i;
	Pt=(PLAYER *)malloc(sizeof(PLAYER));
	if(Pt!=NULL)
	{
		scanf("%d%s%d%d%d",&Pt->account,Pt->name,&Pt->HP,&Pt->power,&Pt->intelligence);
		head=Pt;
		prePt=Pt;
		for(i=1;i<num;i++)
		{
			Pt=(PLAYER *)malloc(sizeof(PLAYER));
			if(Pt!=NULL)
			{
				scanf("%d%s%d%d%d",&Pt->account,Pt->name,&Pt->HP,&Pt->power,&Pt->intelligence);
				Pt->next=Pt;
				prePt=Pt;
				
			}
			else
			{
				printf("Failed.\n");
				exit(0);
			}
		}
	}
	else
	{
		printf("Failed.\n");
		exit(0);
	}
	Pt->next=NULL;
    //或者prePt=NULL;
	return head;
}

二,增加查找操作

/*创建一个单向链表3.0*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/*准备工作,包含数据域和指针域的结构体*/
typedef struct player
{
	int account;
	char name[20];
	int HP;
	int power;
	int intelligence;
	struct player *next;
}PLAYER;
PLAYER *Build(int num);/*创建若干个节点的链表*/
PLAYER *FindLast(PLAYER *head);/*通过头指针查找尾节点*/
PLAYER *FindX(PLAYER *head,int index);/*通过头指针查找第x个节点*/
int main()
{
	int n,x;
	/*打算要多少个节点*/
	printf("打算要几个节点?\n");
	scanf("%d",&n);
	/*查找第x个节点*/
	printf("查找第几个节点?\n");
	scanf("%d",&x);
	/*实际操作*/
	printf("Please input the data.\n");
	printf("account   name    HP    power    inteligence\n");
	PLAYER *head=Build(n);
	printf("The first player's name is: %s\n",head->name);
	/*查找尾节点*/
	PLAYER *last=FindLast(head);
	printf("The last player's power is: %d\n",last->power);
	/*查找第x个节点*/
	PLAYER *X=FindX(head,x);
	printf("The %dth player's intelligence is: %d\n",x,X->intelligence);
	return 0;
}
PLAYER * Build(int num)
{
	/*一,创建节点*/
	/*二,连接,给指针与赋上后继节点的地址值*/
	/*三,确定头指针*/
	/*头指针类型要和节点里的一致*/
	/*四,确定尾节点*/
	/*最后返回头指针*/
	PLAYER *Pt,*prePt,*head;
	int i;
	Pt=(PLAYER *)malloc(sizeof(PLAYER));
	if(Pt!=NULL)
	{
		scanf("%d%s%d%d%d",&Pt->account,Pt->name,&Pt->HP,&Pt->power,&Pt->intelligence);
		head=Pt;
		prePt=Pt;
	}
	else
	{
		printf("Failed.\n");
		exit(0);
	}
	for(i=1;i<num;i++)
		{
			Pt=(PLAYER *)malloc(sizeof(PLAYER));
			if(Pt!=NULL)
			{
				scanf("%d%s%d%d%d",&Pt->account,Pt->name,&Pt->HP,&Pt->power,&Pt->intelligence);
				prePt->next=Pt;
				prePt=Pt;
				
			}
			else
			{
				printf("Failed.\n");
				exit(0);
			}
		}
	Pt->next=NULL;
	return head;
}
PLAYER *FindLast(PLAYER *head)
{
	PLAYER *pr;
	pr=head;/*存储当前节点*/
	/*查找尾节点,当前节点指针域是否为空*/
	while(pr->next!=NULL)
	{
		pr=pr->next;
	}
	return pr;
}
PLAYER *FindX(PLAYER *head,int index)
{
	int i=1;
	PLAYER *pr;
	pr=head;/*存储当前节点*/
	/*查找第x个节点,当前节点指针域是否为空;0-n-1&&1-n,即第一个节点是头节点*/
	while(i<index&&pr!=NULL)//pr!=NULL是为了防止越界操作,即index>n的情况,当前的指针域不能是空指针
	{
		pr=pr->next;
		i++;
	}
	return pr;
}

三,增加插入操作

/*创建一个单向链表3.0*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/*准备工作,包含数据域和指针域的结构体*/
typedef struct player
{
	int account;
	char name[20];
	int HP;
	int power;
	int intelligence;
	struct player *next;
}PLAYER;
PLAYER *Build(int num);/*创建若干个节点的链表*/
PLAYER *FindLast(PLAYER *head);/*通过头指针查找尾节点*/
PLAYER *FindX(PLAYER *head,int index);/*通过头指针查找第x个节点*/
PLAYER *InsertLast(PLAYER *head);/*向单向链表的尾部插入一个节点*/
PLAYER *InsertX(PLAYER *head,int index);/*向单向链表中某节点后插入一个节点*/
int main()
{
	int n,x;
	/*打算要多少个节点*/
	printf("打算要几个节点?\n");
	scanf("%d",&n);
	printf("Please input the data.\n");
	printf("account   name    HP    power    inteligence\n");
	/*实际操作*/
	/*创建若干节点的链表
	PLAYER *head=Build(n);*/
	/*查找头节点
	printf("The first player's name is: %s\n",head->name);*/
	/*查找尾节点
	PLAYER *last=FindLast(head);
	printf("The last player's power is: %d\n",last->power);*/
	/*查找第X个节点
	printf("查找第几个节点?\n");
	scanf("%d",&x);
	printf("The %dth player's intelligence is: %d\n",x,X->intelligence);*/
	/*向尾部插入一个节点
	printf("向尾部插入一个节点\n");
	head=InsertLast(head);*/
	/*向某节点后插入一个节点
	printf("向哪个节点后插入新的节点?\n");
	scanf("%d",&x);
	head=InsertX(head,x);*/
	return 0;
}
PLAYER * Build(int num)
{
	/*一,创建节点*/
	/*二,连接,给指针与赋上后继节点的地址值*/
	/*三,确定头指针*/
	/*头指针类型要和节点里的一致*/
	/*四,确定尾节点*/
	/*最后返回头指针*/
	PLAYER *Pt,*prePt,*head;
	int i;
	Pt=(PLAYER *)malloc(sizeof(PLAYER));
	if(Pt!=NULL)
	{
		scanf("%d%s%d%d%d",&Pt->account,Pt->name,&Pt->HP,&Pt->power,&Pt->intelligence);
		head=Pt;
		prePt=Pt;
	}
	else
	{
		printf("Failed.\n");
		exit(0);
	}
	for(i=1;i<num;i++)
		{
			Pt=(PLAYER *)malloc(sizeof(PLAYER));
			if(Pt!=NULL)
			{
				scanf("%d%s%d%d%d",&Pt->account,Pt->name,&Pt->HP,&Pt->power,&Pt->intelligence);
				prePt->next=Pt;
				prePt=Pt;
				
			}
			else
			{
				printf("Failed.\n");
				exit(0);
			}
		}
	Pt->next=NULL;
	return head;
}
PLAYER *FindLast(PLAYER *head)
{
	PLAYER *pr;
	pr=head;/*存储当前节点*/
	/*查找尾节点,当前节点指针域是否为空*/
	while(pr->next!=NULL)
	{
		pr=pr->next;
	}
	return pr;
}
PLAYER *FindX(PLAYER *head,int index)
{
	int i=1;
	PLAYER *pr;
	pr=head;/*存储当前节点*/
	/*查找第x个节点,当前节点指针域是否为空;0-n-1&&1-n,即第一个节点是头节点*/
	while(i<index&&pr!=NULL)//pr!=NULL是为了防止越界操作,即index>n的情况,当前的指针域不能是空指针
	{
		pr=pr->next;
		i++;
	}
	return pr;
}
PLAYER *InsertLast(PLAYER *head)
{
	PLAYER *prePt,*Pt;/*这俩的作用跟创建时的是基本一样的*/
	Pt=(PLAYER *)malloc(sizeof(PLAYER));/*给新插入格子申请空间*/
	scanf("%d%s%d%d%d",&Pt->account,Pt->name,&Pt->HP,&Pt->power,&Pt->intelligence);/*新插入格子的数据域*/
	/*下面的赋值是关键,不多说,画图理解吧*/
	prePt=FindLast(head);/*首先找到尾节点,并赋值给中介格子(存放当前节点,对此处而言是尾节点,的地址)*/
	prePt->next=Pt;/*把这个格子的指针域的值改成新插入的结点的地址*/
	Pt->next=NULL;/*把新插入的格子的指针域调成空,不指向任何区域*/
	return head;/*最后别忘了返回头指针,链表的‘车头’必须时刻清楚*/
}
PLAYER *InsertX(PLAYER *head,int index)
{
	PLAYER *prePt,*Pt;/*这俩的作用跟创建时的是基本一样的*/
	Pt=(PLAYER *)malloc(sizeof(PLAYER));/*给新插入格子申请空间*/
	scanf("%d%s%d%d%d",&Pt->account,Pt->name,&Pt->HP,&Pt->power,&Pt->intelligence);/*新插入格子的数据域*/
	prePt=FindX(head,index);
	if(prePt!=NULL)
	{
		/*可不能颠倒顺序,颠倒了就相当于自查,不能丢失后继结点的地址*/
		Pt->next=prePt->next;
		prePt->next=Pt;
	}
	else/*如果没找到这个节点*/
	{
		printf("There is no such node\n");
	}
	return head;
}

四,增加删除操作

/*创建一个单向链表3.0*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/*准备工作,包含数据域和指针域的结构体*/
typedef struct player
{
	int account;
	char name[20];
	int HP;
	int power;
	int intelligence;
	struct player *next;
}PLAYER;
PLAYER *Build(int num);/*创建若干个节点的链表*/
PLAYER *FindLast(PLAYER *head);/*通过头指针查找尾节点*/
PLAYER *FindX(PLAYER *head,int index);/*通过头指针查找第x个节点*/
PLAYER *InsertLast(PLAYER *head);/*向单向链表的尾部插入一个节点*/
PLAYER *InsertX(PLAYER *head,int index);/*向单向链表中某节点后插入一个节点*/
PLAYER *Delete(PLAYER *head,int index);/*删除哪个节点*/
int main()
{
	int n,x;
	/*打算要多少个节点*/
	printf("打算要几个节点?\n");
	scanf("%d",&n);
	printf("Please input the data.\n");
	printf("account   name    HP    power    inteligence\n");
	/*实际操作*/
	/*创建若干节点的链表
	PLAYER *head=Build(n);*/
	/*查找头节点
	printf("The first player's name is: %s\n",head->name);*/
	/*查找尾节点
	PLAYER *last=FindLast(head);
	printf("The last player's power is: %d\n",last->power);*/
	/*查找第X个节点
	printf("查找第几个节点?\n");
	scanf("%d",&x);
	printf("The %dth player's intelligence is: %d\n",x,X->intelligence);*/
	/*向尾部插入一个节点
	printf("向尾部插入一个节点\n");
	head=InsertLast(head);*/
	/*向某节点后插入一个节点
	printf("向哪个节点后插入新的节点?\n");
	scanf("%d",&x);
	head=InsertX(head,x);*/
	/*删除哪个节点
	printf("删除哪个节点");
	scanf("%d",&x);
	head=Delete(head,x);*/
	return 0;
}
PLAYER * Build(int num)
{
	/*一,创建节点*/
	/*二,连接,给指针与赋上后继节点的地址值*/
	/*三,确定头指针*/
	/*头指针类型要和节点里的一致*/
	/*四,确定尾节点*/
	/*最后返回头指针*/
	PLAYER *Pt,*prePt,*head;
	int i;
	Pt=(PLAYER *)malloc(sizeof(PLAYER));
	if(Pt!=NULL)
	{
		scanf("%d%s%d%d%d",&Pt->account,Pt->name,&Pt->HP,&Pt->power,&Pt->intelligence);
		head=Pt;
		prePt=Pt;
	}
	else
	{
		printf("Failed.\n");
		exit(0);
	}
	for(i=1;i<num;i++)
		{
			Pt=(PLAYER *)malloc(sizeof(PLAYER));
			if(Pt!=NULL)
			{
				scanf("%d%s%d%d%d",&Pt->account,Pt->name,&Pt->HP,&Pt->power,&Pt->intelligence);
				prePt->next=Pt;
				prePt=Pt;
				
			}
			else
			{
				printf("Failed.\n");
				exit(0);
			}
		}
	Pt->next=NULL;
	return head;
}
PLAYER *FindLast(PLAYER *head)
{
	PLAYER *pr;
	pr=head;/*存储当前节点*/
	/*查找尾节点,当前节点指针域是否为空*/
	while(pr->next!=NULL)
	{
		pr=pr->next;
	}
	return pr;
}
PLAYER *FindX(PLAYER *head,int index)
{
	int i=1;
	PLAYER *pr;
	pr=head;/*存储当前节点*/
	/*查找第x个节点,当前节点指针域是否为空;0-n-1&&1-n,即第一个节点是头节点*/
	while(i<index&&pr!=NULL)//pr!=NULL是为了防止越界操作,即index>n的情况,当前的指针域不能是空指针
	{
		pr=pr->next;
		i++;
	}
	return pr;
}
PLAYER *InsertLast(PLAYER *head)
{
	PLAYER *prePt,*Pt;/*这俩的作用跟创建时的是基本一样的*/
	Pt=(PLAYER *)malloc(sizeof(PLAYER));/*给新插入格子申请空间*/
	scanf("%d%s%d%d%d",&Pt->account,Pt->name,&Pt->HP,&Pt->power,&Pt->intelligence);/*新插入格子的数据域*/
	/*下面的赋值是关键,不多说,画图理解吧*/
	prePt=FindLast(head);/*首先找到尾节点,并赋值给中介格子(存放当前节点,对此处而言是尾节点,的地址)*/
	prePt->next=Pt;/*把这个格子的指针域的值改成新插入的结点的地址*/
	Pt->next=NULL;/*把新插入的格子的指针域调成空,不指向任何区域*/
	return head;/*最后别忘了返回头指针,链表的‘车头’必须时刻清楚*/
}
PLAYER *InsertX(PLAYER *head,int index)
{
	PLAYER *prePt,*Pt;/*这俩的作用跟创建时的是基本一样的*/
	Pt=(PLAYER *)malloc(sizeof(PLAYER));/*给新插入格子申请空间*/
	scanf("%d%s%d%d%d",&Pt->account,Pt->name,&Pt->HP,&Pt->power,&Pt->intelligence);/*新插入格子的数据域*/
	prePt=FindX(head,index);
	if(prePt!=NULL)
	{
		/*可不能颠倒顺序,颠倒了就相当于自查,不能丢失后继结点的地址*/
		Pt->next=prePt->next;
		prePt->next=Pt;
	}
	else/*如果没找到这个节点*/
	{
		printf("There is no such node\n");
	}
	return head;
}
PLAYER *Delete(PLAYER *head,int index)
{
	//删除过程中,我们需要接触三个地址
	PLAYER *Pt=NULL,*prePt=NULL;
	prePt=FindX(head,index-1);
	//找到一个节点/地址实际上是获得了两个地址,我们要做的就是取到两个我们需要的地址,问题是取当前节点还是它的前驱节点,肯定不能取后继节点,因为它只有一个我们需要的值
	//但是取当前节点的话,我们得查找两次,因为由它指向的地址所指的是我们所不需要的,所以要减少查找次数且不易出错的话,还是取前驱节点好
	Pt = prePt->next;
	if(Pt!=NULL)//我甚至觉得判断prePt更好
	{
		prePt->next=Pt->next;
		free(Pt);
	}
	else
	{
		printf("There is no such node\n");
	}
	return head;
}

/************************************************************************/

数据结构之后

创建结点

/*****创建结点*****/
typedef int datatype;
typedef struct link_node
{
	datatype info;
	struct link_node *next;
}node;
typedef node *linklist;

头插创建单链表

/*******头插:新结点往前加********/
linklist creatbystack()
{
	linklist head=NULL,p;
	datatype x;
	while(x!=0)
	{
		p=(linklist)malloc(sizeof(node));
		p->info=x;
		p->next=head;
		head=p;
		scanf("%d",&x);
	}
	return head;
}

尾插创建单链表

/*******尾插:队列方式建立********/
linklist ctreatbyqueue()
{
	linklist head=NULL,r=NULL,s;
	//r为链尾指针,每次新的节点链在r的后面,使其成为新的表尾结点 
	datatype x;
	scanf("%d",&x);
	while(x!=0)
	{
		s=(linklist)malloc(sizeof(node));
		s->info=x;
		if(head==NULL) head=s;//新结点插入新表 
		else r->next=s;
		r=s;
		scanf("%d",&x);
	}
	if(r!=NULL)	r->next=NULL;
	return head; 
}

输出(不带头结点)

/************打印结点值************/
void print(linklist head)
{
	linklist p;
	p=head;
	while(p)
	{
		printf("%5d",p->info);
		p=p->next;
	}
	printf("\n");
}

释放(不带头结点)

/**********释放不带头结点的单链表****/
void delList(linklist head)
{
	linklist p=head;
	/*一个一个结点释放*/
	while(p!=NULL)
	{
		head=p->next;
		free(p);
		p=head;
	}
}

删除第一个值为x的结点(不带头结点的链表)

linklist delx(linklist head,datatype x)
{
linklist pt=head,pre=NULL;
while(pt!=NULL&&pt->info!=x)
{
pre=pt;
pt=pt->next;
}
if(pt!=NULL)//若进入以上循环,出循环时,pre指向x前的节点,pt指向值为x的结点
{
if(pre==NULL)//没进循环,第一个结点的值就是x
head=pt-next;
else//一般情况,值为x的结点在中间,包括值在最后一个结点的情况
pre->next=pt->next;
free(pt);
}
return head;//如果这个链表的结点里压根没有x,直接这一步就好了
}

删除所有值为x的结点(不带头结点)

linklist delallx(linklist head,datatype x)
{
linklist pre=NULL,pt=head;
while(pt)
{
while(pt!=NULL&&pt->info!=x)//查找值为x的结点
{
pre=pt;
pt=pt->next;
}
if(pt!=NULL)//删除,释放这个节点
{
if(pre==NULL)
{
head=pt->next;
free(pt);
pt=head;//要接上,pt要继续用
}
else
{
pre->next=pt->next;
free(pt);
pt=pre->next;//接上,pt要有指向
}
}
}
return   head;
}

逆序链表(原地倒置)

法一

linklist reverse1(linklist head)
{
linklist s,r;
s=head;
head=NULL;
while(s)
{
r=s;
s=s->next;
r->next=head;
head=r;
}
return head;
}

法二

void reverse2(linklist *head)
{
linklist s,r;
s=*head;
*head=NULL;
while(s)
{
r=s;
s=s->next;
r->next=*head;
*head=r;
}
}

插入值为x的链表(顺序为升序)

linklist insert(linklist head,datatype x)
{
linklist p,r,s;//s是因为插入了一个新的结点,所以要创建一个新的
p=NULL;
r=head;
while(r!=NULL && r->info < x)//查找值为x的结点
{
p=r;
r=r->next;
}
s=(linklist)malloc(sizeof(node));//一般情况s插在r前面(x<=r->info)
s->info=x;
if(p!=NULL)//一般情况
{
s->next=r;
p->next=s;
}
else//特殊情况:x<=第一个结点的值,直接插在前面,涉及head
{
s->next=head;
head=s;
}
return head;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值