习题11-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;
}
  • 8
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
一.单选题(共10题,5) 1线性表采用链式存储结构时,其地址( )。A、必须是连续的B、部地址必须是连续的C、一定是不连续的D、连续与否均可以正确答案: D 2带头结点单链表head为空的判断条件是( )。A、head=NULLB、head->next=NULLC、head->next=headD、head!=NULL正确答案: B 3将两个各有n个元素的有序表归并成一个有序表,其最少的比较次数是( )。A、nB、2n-1C、 2nD、n-1正确答案: A 4在一个单链表,已知q所指结点是p所指结点的前趋结点,若在q和p之间插入s结点,则执行( )。A、 s->next=p->next;p->next=sB、p->next=s->next;s->next=pC、q->next=s;s->next=pD、p->next=s;s->next=q正确答案: C 5向一个有 127 个元素的顺序表插入一个新元素并保持原来顺序不变,平均要移动( )个元素。A、64B、63C、63.5D、7正确答案: C 插入 n/2 删除 n-1/2 查询 n+1/2 6若某线性表最常用的操作是在最后一个元素之后插入一个元素和删除第一个元素,则采用( )存储方式最节省运算时间。A、单链表B、仅有头指针的单循环链表C、双链表D、仅有尾指针的单循环链表正确答案: D 7若长度为n的线性表采用顺序存储结构,在其第个i位置插入一个新元素算法的时间复杂度为( )。A、 O(log2n)B、O(1)C、O(n)D、O(n2) 正确答案: C 8线性表的静态链表存储结构与顺序存储结构相比优点是( )。A、所有的操作算法简单B、便于插入和删除C、便于利用零散的存储空间D、便于随机存取正确答案: B 9在一个单链表, 若删除 p 所指结点的后续结点, 则执行( )A、s->next=p;p->next=s;B、s->next=p->next;p=s;C、s->next=p->next;p->next=s;D、p->next=s;s->next=p;正确答案: B 10一个线性表第一个元素的存储地址是 100, 每个元素的长度为 2,则第 5 个元素的地址是( )A、110B、108C、100D、120

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值