PTA链表习题集合[11-2-1~11-2-9]

PTA链表习题集合[11-2-1~11-2-9]

1.实验11-2-1 建立学生信息链表 (20分)

本题要求实现一个将输入的学生成绩组织成单向链表的简单函数。

函数接口定义:(尾插法)

void input();    

该函数利用scanf从输入中获取学生的信息,并将其组织成单向链表。链表节点结构定义如下:

struct stud_node {
    int              num;      /*学号*/
    char             name[20]; /*姓名*/
    int              score;    /*成绩*/
    struct stud_node *next;    /*指向下个结点的指针*/
};      

单向链表的头尾指针保存在全局变量headtail中。

输入为若干个学生的信息(学号、姓名、成绩),当输入学号为0时结束。

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct stud_node {
     int    num;
     char   name[20];
     int    score;
     struct stud_node *next;
};
struct stud_node *head, *tail;

void input();

int main()
{
    struct stud_node *p;
	
    head = tail = NULL;
    input();
    for ( p = head; p != NULL; p = p->next )
        printf("%d %s %d\n", p->num, p->name, p->score);

    return 0;
}

/* 你的代码将被嵌在这里 */

      
    

输入样例:

1 zhang 78
2 wang 80
3 li 75
4 zhao 85
0    

输出样例:

1 zhang 78
2 wang 80
3 li 75
4 zhao 85

函数代码:

void input()
{
	//已存在head,tail;
	int    num;
    char   name[20];
    int    score;
	struct stud_node *p;
	//输入学号姓名班级 
	scanf("%d",&num);
	//学号不为0时循环 
	while(num!=0)
	{
		scanf("%s%d",name,&score);
		//申请新结点 
		p = (struct stud_node*)malloc(sizeof(struct stud_node));
		p->next=NULL; //新结点的下一个结点指空 
		//赋值新结点 
		p->num=num;
		strcpy(p->name,name);
		p->score=score;
		//判断是否为首结点,是则直接赋值,不是则尾接 
		if(tail==NULL)
			head=p;
		else
		{
			tail->next=p;	
		}
		tail=p;	//尾指针移动 
		scanf("%d",&num);
	} 
} 

2.实验11-2-2学生成绩链表处理(20分)

本题要求实现两个函数,一个将输入的学生成绩组织成单向链表;另一个将成绩低于某分数线的学生结点从链表中删除。

函数接口定义:

struct stud_node *createlist();
struct stud_node *deletelist( struct stud_node *head, int min_score );   

函数createlist利用scanf从输入中获取学生的信息,将其组织成单向链表,并返回链表头指针。链表节点结构定义如下:

struct stud_node {
    int              num;      /*学号*/
    char             name[20]; /*姓名*/
    int              score;    /*成绩*/
    struct stud_node *next;    /*指向下个结点的指针*/
};   

输入为若干个学生的信息(学号、姓名、成绩),当输入学号为0时结束。

函数deletelist从以head为头指针的链表中删除成绩低于min_score的学生,并返回结果链表的头指针。

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>

struct stud_node {
     int    num;
     char   name[20];
     int    score;
     struct stud_node *next;
};

struct stud_node *createlist();
struct stud_node *deletelist( struct stud_node *head, int min_score );

int main()
{
    int min_score;
    struct stud_node *p, *head = NULL;

    head = createlist();
    scanf("%d", &min_score);
    head = deletelist(head, min_score);
    for ( p = head; p != NULL; p = p->next )
        printf("%d %s %d\n", p->num, p->name, p->score);

    return 0;
}

/* 你的代码将被嵌在这里 */

      
    

输入样例:

1 zhang 78
2 wang 80
3 li 75
4 zhao 85
0
80    

输出样例:

2 wang 80
4 zhao 85

函数代码:

struct stud_node *createlist()
{
	//已存在head,tail;
	int    num;
	char   name[20];
    int    score;
	struct stud_node *p,*head=NULL,*tail;
	tail=head;
	//输入学号 
	scanf("%d",&num);
	//学号不为0时循环 
	while(num!=0)
	{
		//申请新结点 
		p = (struct stud_node*)malloc(sizeof(struct stud_node));
		//赋值新结点
		scanf("%s %d",p->name,&p->score);
		p->num=num;
		p->next=NULL; //新结点的下一个结点指空 
		//判断是否为首结点,是则直接赋值,不是则尾接 
		if(tail==NULL)
			head=p;
		else
		{
			tail->next=p;	
		}
		tail=p;	//尾指针移动 
		scanf("%d",&num);
	} 
	
	return head;
} 

struct stud_node *deletelist( struct stud_node *head, int min_score )
{
	//删除成绩低于min_score的学生,返回头指针 
	struct stud_node *move,*front;
	move=head;
	front=NULL; 
	while(move)
	{
		//若符合小于min_score 
		if(move->score<min_score)
		{
			//若为第一个,则移动头指针后移一位 
			if(front==NULL)
				head=head->next;
			//若非第一位则,move的前一个节点指向move的后一个节点,跳过move 
			else
				front->next=move->next;
	
		}//不符合则front移动到当前move的位置  保留前一个结点做标记 
		else
			front=move;
		//move向下一个结点移动			
		move=move->next;
	} 
	
	return head;	
}


3.实验11-2-3逆序数据建立链表 (20分)

本题要求实现一个函数,按输入数据的逆序建立一个链表。

函数接口定义:(头插法)

struct ListNode *createlist();    

函数createlist利用scanf从输入中获取一系列正整数,当读到−1时表示输入结束。按输入数据的逆序建立一个链表,并返回链表头指针。链表节点结构定义如下:

struct ListNode {
    int data;
    struct ListNode *next;
};    

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>

struct ListNode {
    int data;
    struct ListNode *next;
};

struct ListNode *createlist();

int main()
{
    struct ListNode *p, *head = NULL;

    head = createlist();
    for ( p = head; p != NULL; p = p->next )
        printf("%d ", p->data);
    printf("\n");

    return 0;
}

/* 你的代码将被嵌在这里 */

    

输入样例:

1 2 3 4 5 6 7 -1    

输出样例:

7 6 5 4 3 2 1 

函数代码:

struct ListNode *createlist()
{
	int data;
	struct ListNode *head = (struct ListNode*)malloc(sizeof(struct ListNode)); //创建一个空的头结点 
	struct ListNode *insert;
	head->next=NULL; //头指针指空 
	insert=head; //建立一个指针指向头结点 
	scanf("%d",&data);
	while(data!=-1)
	{
		struct ListNode *p = (struct ListNode*)malloc(sizeof(struct ListNode)); //申请新结点 
		p->data=data; 
		//头插法核心 
		p->next=insert->next; //新节点指向头指针的下一个节点 
		insert->next=p;	//头指针指向新节点 
		scanf("%d",&data);
	}
		
	return head->next;	//返回的不是头指针而是首个结点,既头指针指向的下一个结点 
} 


4.实验11-2-4 删除单链表偶数节点(20分)

本题要求实现两个函数,分别将读入的数据存储为单链表、将链表中偶数值的结点删除。链表结点定义如下:

struct ListNode {
    int data;
    struct ListNode *next;
};   

函数接口定义:

struct ListNode *createlist();
struct ListNode *deleteeven( struct ListNode *head );   
    

函数createlist从标准输入读入一系列正整数,按照读入顺序建立单链表。当读到−1时表示输入结束,函数应返回指向单链表头结点的指针。

函数deleteeven将单链表head中偶数值的结点删除,返回结果链表的头指针。

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>

struct ListNode {
    int data;
    struct ListNode *next;
};

struct ListNode *createlist();
struct ListNode *deleteeven( struct ListNode *head );
void printlist( struct ListNode *head )
{
     struct ListNode *p = head;
     while (p) {
           printf("%d ", p->data);
           p = p->next;
     }
     printf("\n");
}

int main()
{
    struct ListNode *head;

    head = createlist();
    head = deleteeven(head);
    printlist(head);

    return 0;
}

/* 你的代码将被嵌在这里 */

        

输入样例:

1 2 2 3 4 5 6 7 -1   

输出样例:

1 3 5 7 

函数代码:

/* 你的代码将被嵌在这里 */
struct ListNode *createlist()
{
	struct ListNode *head=NULL,*p,*last;
    int n;
	last=head; //last指针用于移动表示链表末尾 
	do{
		scanf("%d",&n); //输入结点数值 
		if(n!=-1)
		{
			p=(struct ListNode *)malloc(sizeof(struct ListNode));  //申请新节点 
			p->data=n; //新节点赋值 
			p->next=NULL; //新节点指空 
			if(last==NULL) //若为头结点时 
				head=p;
			else
				last->next=p; //非头结点时,尾接 
			last=p;	//标志位移动到新节点处		
		}
		else
			break;	
	}while(n!=-1);
	
	return head;				
}

struct ListNode *deleteeven( struct ListNode *head )
{
	//删除偶数结点 
	struct ListNode *move,*front;
	move=head;
	front=NULL; 
	while(move)
	{
		//若符合data为偶数 
		if((move->data)%2==0)
		{
			//若为第一个,则移动头指针后移一位 
			if(front==NULL)
				head=head->next;
			//若非第一位则,move的前一个节点指向move的后一个节点,跳过move 
			else
				front->next=move->next;
	
		}//不符合则front移动到当前move的位置  保留前一个结点做标记 
		else
			front=move;
		//move向下一个结点移动			
		move=move->next;
	} 
	
	return head;	
} 

5.实验11-2-5链表拼接(20分)

本题要求实现一个合并两个有序链表的简单函数。链表结点定义如下:

struct ListNode {
    int data;
    struct ListNode *next;
};    

函数接口定义:

struct ListNode *mergelists(struct ListNode *list1, struct ListNode *list2);   

其中list1list2是用户传入的两个按data升序链接的链表的头指针;函数mergelists将两个链表合并成一个按data升序链接的链表,并返回结果链表的头指针。

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>

struct ListNode {
    int data;
    struct ListNode *next;
};

struct ListNode *createlist(); /*裁判实现,细节不表*/
struct ListNode *mergelists(struct ListNode *list1, struct ListNode *list2);
void printlist( struct ListNode *head )
{
     struct ListNode *p = head;
     while (p) {
           printf("%d ", p->data);
           p = p->next;
     }
     printf("\n");
}

int main()
{
    struct ListNode  *list1, *list2;

    list1 = createlist();
    list2 = createlist();
    list1 = mergelists(list1, list2);
    printlist(list1);
	
    return 0;
}

/* 你的代码将被嵌在这里 */

       

输入样例:

1 3 5 7 -1
2 4 6 -1    

输出样例:

1 2 3 4 5 6 7 

函数代码:

/* 你的代码将被嵌在这里 */
struct ListNode *mergelists(struct ListNode *list1, struct ListNode *list2)
{
	//函数mergelists将两个链表合并成一个按data升序链接的链表 --合并---升序 
	//思路1.是相当于删除后一个链表的结点,在插入到前一个链表里。 
	//思路2,先合并两个链表,在利用指针变量做若干次冒泡排序。
	
	if(list1==NULL&&list2)
		return list2;
	if(list2==NULL&&list1)
		return list1;
	if(list1==NULL&&list2==NULL)
		return NULL;
	struct ListNode *move1,*move2,*save,*front; //move1.2 分别用于移动,save用来指向从list2取下结点的地址 
	move2=list2;
	move1=list1;
	while(move2)
	{
		//<---取结点--->
		save=move2; //保存list2当前节点 
		move2=move2->next; //list2首结点后移 
		save->next=NULL; //当前节点指空 ,取下结点 
		
		//<---插入结点到符合条件位置--->
		//重置move1首结点地址,front指针 
		move1=list1;
		front=NULL; 
		while(move1)
		{	 
			if(save->data<move1->data)
			{
				if(front)
				{
					//头插法核心 ,当data的值在list1中间时
					save->next=front->next;
					front->next=save;
					break; 
				}else{
					//当data的值比list1所有值都小的时候 
					save->next=list1;
					list1=save;
					break;
				}	
			}else
				front=move1;	
			move1=move1->next;
		}
					
		//尾插法 当data的值比list1所有值都大的时候 	
		if(move1==NULL)
		{
			front->next=save;	
		}	
		
	} 
	
	//返回list1首地址 
	return list1;	
} 
  

6.实验11-2-6 奇数值结点链表 (20分)

本题要求实现两个函数,分别将读入的数据存储为单链表、将链表中奇数值的结点重新组成一个新的链表。链表结点定义如下:

struct ListNode {
    int data;
    ListNode *next;
};    

函数接口定义:

struct ListNode *readlist();
struct ListNode *getodd( struct ListNode **L );
   

函数readlist从标准输入读入一系列正整数,按照读入顺序建立单链表。当读到−1时表示输入结束,函数应返回指向单链表头结点的指针。

函数getodd将单链表L中奇数值的结点分离出来,重新组成一个新的链表。返回指向新链表头结点的指针,同时将L中存储的地址改为删除了奇数值结点后的链表的头结点地址(所以要传入L的指针)。

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>

struct ListNode {
    int data;
    struct ListNode *next;
};

struct ListNode *readlist();
struct ListNode *getodd( struct ListNode **L );
void printlist( struct ListNode *L )
{
     struct ListNode *p = L;
     while (p) {
           printf("%d ", p->data);
           p = p->next;
     }
     printf("\n");
}

int main()
{
    struct ListNode *L, *Odd;
    L = readlist();
    Odd = getodd(&L);
    printlist(Odd);
    printlist(L);

    return 0;
}

/* 你的代码将被嵌在这里 */

      
    

输入样例:

1 2 2 3 4 5 6 7 -1   

输出样例:

1 3 5 7 
2 2 4 6 

函数代码:

/* 你的代码将被嵌在这里 */
struct ListNode *readlist()
{
	struct ListNode *head=NULL,*p,*last;
    int n;
	last=head; //last指针用于移动表示链表末尾 
	do{
		scanf("%d",&n); //输入结点数值 
		if(n!=-1)
		{
			p=(struct ListNode *)malloc(sizeof(struct ListNode));  //申请新节点 
			p->data=n; //新节点赋值 
			p->next=NULL; //新节点指空 
			if(last==NULL) //若为头结点时 
				head=p;
			else
				last->next=p; //非头结点时,尾接 
			last=p;	//标志位移动到新节点处		
		}
		else
			break;	
	}while(n!=-1);
	
	return head;				
}

struct ListNode *getodd( struct ListNode **L )
{
	//奇数分离构成新链表,返回删除奇数的链表的头结点 
	struct ListNode *odd=NULL,*last,*p,*q,*k;
	last=odd;  //用于奇数链表链表 插入新节点
	p=*L;    //表示原链表移动指针 
	q=NULL; //q初始化,作为原链表移动指针前一个节点的标记 
	while(p)
	{
		if((p->data)%2) //data取余2为 1 则为奇数,删除节点 
		{
			if(q&&p!=*L) //非L收个节点就是奇数的情况 
			{
				k=p; //保存奇数节点 
				q->next=p->next; //删除奇数节点 
				
				if(last!=NULL)    //插入odd链表 
					last->next=k;
				else
					odd=k;
				last=k;		
			}	
			else //L的第一个就是奇数的情况  
			{ 
				k=p;              //保存奇数节点 
				*L=p->next;       //头结点向后移动,删除奇数节点 
				
				if(last!=NULL)    //插入odd链表 
					last->next=k;
				else
					odd=k;
				last=k;		
			}
		}
		else
			q=p; //未找到奇数节点,则用q保留当前位置 		 
		p=p->next; //p指针继续向下移动
        if(last) //odd链表非空则
		    last->next=NULL;  //odd末尾指针指空 
	} 
	return odd;		
}

7.实验11-2-7 统计专业人数 (15分)

本题要求实现一个函数,统计学生学号链表中专业为计算机的学生人数。链表结点定义如下:

struct ListNode {
    char code[8];
    struct ListNode *next;
};    

这里学生的学号共7位数字,其中第2、3位是专业编号。计算机专业的编号为02。

函数接口定义:

int countcs( struct ListNode *head );   

其中head是用户传入的学生学号链表的头指针;函数countcs统计并返回head链表中专业为计算机的学生人数。

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct ListNode {
    char code[8];
    struct ListNode *next;
};

struct ListNode *createlist(); /*裁判实现,细节不表*/
int countcs( struct ListNode *head );

int main()
{
    struct ListNode  *head;

    head = createlist();
    printf("%d\n", countcs(head));
	
    return 0;
}

/* 你的代码将被嵌在这里 */

      
    

输入样例:

1021202
2022310
8102134
1030912
3110203
4021205
#    

输出样例:

3

函数代码:

int countcs( struct ListNode *head )
{
	//统计并返回head链表中专业为计算机的学生人数
	int i,count=0,item;
	struct ListNode *p=head;
    //p指针用来遍历链表
	while(p)
	{
		//只读取code数组下标为1.2的字符
        for(item=0,i=1;i<=2;i++)
		{
			//字符转整数
            item=item*10+(p->code[i]-'0');
		}
		//判断是否为2
		if(item==2)
		{
			count++;
		}
        //移动指针
		p=p->next;
	}
	//返回计数
	return count;
}

8.实验11-2-8 单链表结点删除 (20分)

本题要求实现两个函数,分别将读入的数据存储为单链表、将链表中所有存储了某给定值的结点删除。链表结点定义如下:

struct ListNode {
    int data;
    ListNode *next;
};

      
    

函数接口定义:

struct ListNode *readlist();
struct ListNode *deletem( struct ListNode *L, int m );

      
    

函数readlist从标准输入读入一系列正整数,按照读入顺序建立单链表。当读到−1时表示输入结束,函数应返回指向单链表头结点的指针。

函数deletem将单链表L中所有存储了m的结点删除。返回指向结果链表头结点的指针。

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>

struct ListNode {
    int data;
    struct ListNode *next;
};

struct ListNode *readlist();
struct ListNode *deletem( struct ListNode *L, int m );
void printlist( struct ListNode *L )
{
     struct ListNode *p = L;
     while (p) {
           printf("%d ", p->data);
           p = p->next;
     }
     printf("\n");
}

int main()
{
    int m;
    struct ListNode *L = readlist();
    scanf("%d", &m);
    L = deletem(L, m);
    printlist(L);

    return 0;
}

/* 你的代码将被嵌在这里 */

      
    

输入样例:

10 11 10 12 10 -1
10

      
    

输出样例:

11 12 

函数代码:

struct ListNode *readlist()
{
	//---**尾插法**--- 
	//定义3个指针变量
	//head用于返回链表的首结点,先初始化指空
	//p 用于申请新节点 
	//last 用于连接head和新节点的一个尾指针,并且每次都停留在链表结尾 
	struct ListNode *head=NULL,*p,*last;
	int n;
	//先把last指向head ,起始时首尾都在一起 
	last=head; 
	
	do{
		//输入节点信息 
		scanf("%d",&n);
		
		//输入值!= -1时 操作 
		if(n!=-1)
		{
			//---申请新节点--- 
			p=(struct ListNode *)malloc(sizeof(struct ListNode));
			p->data=n;
			p->next=NULL; //申请的新节点初始化,下一个节点指空 
			
			//---连接节点----
			//head需要返回,不能用来移动,当检测到尾指针指空,表示首尾指针并未有任何值 
			if(last==NULL)
				head=p; //直接把第一个节点赋值到head   
			else
				last->next=p;  //若last非空 则把p连接到last后一个节点 head->last->p->null; 
			last=p; //连接完后last移动到到p上,既移动到新的结尾 	head->last->p1->last(p)->null;
		}
		else  
			break;
						
	}while(n!=-1);// -1结束循环 
	
	return head;
				
}

struct ListNode *deletem( struct ListNode *L,int m )
{
    //--由于单链表遍历是不可逆的---
	//设置两个指针一个控制移动,一个用于连接(防止断链)
	 
	struct ListNode *p,*q;
    p=L;  //p用于移动 
    q=NULL;  //q初始化 
    
    //当p非空时 
    while(p)
    {
		//若data为m 
		if(p->data==m)
    	{
    		//情况1:中间节点或者末尾节点是m ,此时 q!=NULL    
			if(q)
				q->next=p->next;    //q->m(p)->x    q->x			
			//情况2:首节点就是m ,此时 q=NULL 
			else
				L=p->next; //则直接移动链表的首结点后移 
		}
		else//data不为m,则q移动到p当前位置,相当于记录p前一个节点 
			q=p;
			
		//p指针移动到下一个节点	
    	p=p->next;
	}
	
    return L;
}

9.实验11-2-9 链表逆置 (20分)

本题要求实现一个函数,将给定单向链表逆置,即表头置为表尾,表尾置为表头。链表结点定义如下:

struct ListNode {
    int data;
    struct ListNode *next;
};    

函数接口定义:

struct ListNode *reverse( struct ListNode *head );    

其中head是用户传入的链表的头指针;函数reverse将链表head逆置,并返回结果链表的头指针。

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>

struct ListNode {
    int data;
    struct ListNode *next;
};

struct ListNode *createlist(); /*裁判实现,细节不表*/
struct ListNode *reverse( struct ListNode *head );
void printlist( struct ListNode *head )
{
     struct ListNode *p = head;
     while (p) {
           printf("%d ", p->data);
           p = p->next;
     }
     printf("\n");
}

int main()
{
    struct ListNode  *head;

    head = createlist();
    head = reverse(head);
    printlist(head);
	
    return 0;
}

/* 你的代码将被嵌在这里 */

      
    

输入样例:

1 2 3 4 5 6 -1   

输出样例:

6 5 4 3 2 1 

函数代码:

struct ListNode *reverse( struct ListNode *head )
{
	//时间复杂度为O(n),空间复杂度为O(1)
  	//特殊情况,空链表
    if(head==NULL)
        return NULL;
     //申请一个空的结点作为头结点
    struct ListNode *fake = (struct ListNode*)malloc(sizeof(struct ListNode));	
	struct ListNode *front,*now,*tail;
	fake->next=head;
	front=head; 
    //当now==NULL时,结束循环 	
	do{
		//指针移动 
		now=front->next;
		if(now==NULL)
			break;
		tail=now->next;
		//头插法 
		front->next=tail;
		now->next=fake->next;
		fake->next=now; 
	}while(1);
	
	return fake->next;
}

图解:

  • 3个指针变量控制,front,now,tail 前中后
  • 把now取下后头插到fake后面,循环重复本次操作,当now==NULL时完成逆置。
    在这里插入图片描述

完结

总结:(待续)

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 算法2-8:链表创建 1. 定义一个链表结构体 2. 初始化头结点 3. 循环读入数据,创建新的结点并插入链表尾部 算法2-9:链表的遍历 1. 从头结点开始,依次遍历链表中的每个结点 2. 对每个结点进行相应的操作 算法2-10:链表的插入 1. 找到要插入的位置 2. 创建新的结点 3. 将新结点插入到链表中 算法2-11链表的删除 1. 找到要删除的结点 2. 将该结点的前驱结点指向该结点的后继结点 3. 释放该结点的内存空间 ### 回答2: 链表是一种非常基础的数据结构,在计算机科学中具有很重要的作用。链表是由若干个节点组成的,每个节点都包含数据和一个指向下一个节点的指针。链表的优点是可以动态地增加或删除节点,而不需要移动其他节点。链表的基本操作包括创建链表、插入节点、删除节点和遍历链表,下面分别介绍。 首先是创建链表的操作。创建链表需要一个头节点,头节点不包含数据,只是用来表示链表的开始。可以通过如下代码来创建一个空链表: ``` typedef struct Node{ int data; struct Node *next; } Node; Node *create_list() { Node *head = (Node*)malloc(sizeof(Node)); head->next = NULL; return head; } ``` 接下来是插入节点操作。插入节点需要先找到要插入的位置,然后修改指针指向。如果要在链表的头部插入节点,可以直接将头指针修改为新节点;如果要在链表的中间或尾部插入节点,则需要遍历链表,找到要插入位置的前一个节点,然后修改前一个节点的next指针即可。如下代码就是在链表尾部插入一个值为value的节点: ``` void insert_node_tail(Node *head, int value){ Node *p = head; while(p->next != NULL){ p = p->next; } Node *new_node = (Node*)malloc(sizeof(Node)); new_node->data = value; new_node->next = NULL; p->next = new_node; } ``` 删除节点操作与插入节点操作类似,也需要找到要删除的位置,然后修改指针指向。如果要删除链表头节点,只需将头指针修改为下一个节点即可;如果要删除中间或尾部的节点,则需要遍历链表,找到要删除位置的前一个节点,然后将其next指针指向下一个节点的next指针即可。如下代码就是删除链表中值为value的第一个节点: ``` void delete_node(Node *head, int value){ Node *p = head; while(p->next != NULL && p->next->data != value){ p = p->next; } if(p->next != NULL){ Node *tmp = p->next; p->next = p->next->next; free(tmp); }else{ printf("值为%d的节点不存在\n", value); } } ``` 最后是遍历链表操作。遍历链表可以使用while循环和指针变量遍历整个链表,将节点的值打印出来即可。如下代码就是遍历链表并打印出每个节点的值: ``` void traverse_list(Node *head){ Node *p = head->next; while(p != NULL){ printf("%d ",p->data); p = p->next; } } ``` 以上就是链表的基本操作,其中涉及到了指针操作、动态内存分配和链表节点的定义等知识点。掌握这些操作能够在实际编程中应用链表这种数据结构,提高算法的效率和代码的可维护性。 ### 回答3: 1.算法2-8:插入节点。 这个算法的目的是向链表中插入新的节点,将新节点放在指定节点的后面。 首先,我们需要通过一个循环找到需要插入的位置,即需要插入节点的前一个节点。 然后,我们将新节点连接到链表中,并将指定节点的下一个节点连接到新节点上。 最后,我们需要检查该插入的位置是否为空,如果为空,则新节点是链表的最后一个节点。 2.算法2-9:删除节点。 该算法的目的是从链表中删除一个指定的节点。 首先,我们需要找到该节点的前一个节点,以便将该节点从链表中删除。 然后,我们需要将该节点从链表中断开,并将该节点的下一个节点连接到前一个节点。 最后,我们需要确保链表中不再有对该节点的引用。 3.算法2-10:查找值。 在链表中查找一个特定的值是很常见的操作。该算法的目的就是查找给定值在链表中的位置。 首先,我们需要从链表的头部开始查找,直到我们找到该值或者到达链表的末尾。 找到值后,我们需要返回该节点在链表中的位置。 如果在整个链表中都没有找到该值,我们需要返回一个错误。 4.算法2-11:遍历链表链表的遍历是指按顺序遍历链表中的每个节点。 该算法的目的就是打印链表中的每个节点的值。 首先,我们需要从链表的头部开始,重复访问链表中的每个节点。 我们可以使用一个循环来遍历整个链表,每次访问一个节点,打印该节点的值,然后移动到下一个节点,直到到达链表的末尾。 如果链表为空,我们将不会打印任何值。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值