王道数据结构课后代码题p40 第1-6题 (c语言代码实现)

目录

1.设计一个递归算法,删除不带头结点的单链表L中的所有值为x的结点(c语言代码实现)图解递归

首先它是一个不带头结点的单链表

我们就得特殊处理

递归的图解 

本题主要代码为

 完整测试代码为

2.在带头结点的单链表工中,删除所有值为X的结点,并释放其空间,假设值为X的结点不唯一,试编写算法以实现上述操作(c语言代码实现)

3.设L为带头结点的单链表,编写算法实现从头到尾反向输出每个结点的值

 4.在带头结点的单链表L中删除一个最小值结点的高效算法(假设最小值唯一) (c语言代码实现)

5.将带头结点的单链表就地逆置,所谓“就地”是指辅助空间复杂度为O(1) (c语言代码实现)王道数据结构课后代码题p40 5.将带头结点的单链表就地逆置,所谓“就地”是指辅助空间复杂度为O(1) (c语言代码实现)-CSDN博客

 6.有一个带头结点的单链表L,设计一个算法使其元素递增有序 (c语言代码实现)


1.设计一个递归算法,删除不带头结点的单链表L中的所有值为x的结点(c语言代码实现)图解递归

 视频讲解(献丑了):p40 第1题 王道数据结构课后代码题c语言代码实现_哔哩哔哩_bilibili

首先它是一个不带头结点的单链表

我们就得特殊处理

我们先让*L==NULL;

然后为s开辟一个新的存储空间,让他等于a[0]的值

下面我们看一下建立无头节点的单链表代码该如何实现

void buildlinklist(linklist* L)
{
    *L = NULL;
    lnode* s, * r = *L;
    int i = 0;
    if (*L == NULL)
    {
        s = (lnode*)malloc(sizeof(lnode));
        s->data = a[0];
        s->next = NULL;
        *L = s;
    }
    r = *L;
        for (i = 1; i < n; i++)
        {
            s = (lnode*)malloc(sizeof(lnode));
            s->data = a[i];
            r->next = s;
            r =s;
        }
    r->next = NULL;
}

递归的图解 

本题主要代码为

void delete(linklist* L,int x)
{
    lnode* p;
    if (*L== NULL) {
        return;
    }
    if((*L)->data == x) 
    {
        p = *L;
        *L = (*L)->next;
        free(p);
        delete(L, x);
    }
    else {
        delete(&(*L)->next, x);
    }
}

 完整测试代码为

#include<stdio.h>
#include<stdlib.h>
typedef struct lnode
{
    int data;
    struct lnode* next;
} lnode, * linklist;
int a[5] = { 1,3,3,4,5 };
int n = 5;
void buildlinklist(linklist* L)
{
    *L = NULL;
    lnode* s, * r = *L;
    int i = 0;
    if (*L == NULL)
    {
        s = (lnode*)malloc(sizeof(lnode));
        s->data = a[0];
        s->next = NULL;
        *L = s;
    }
    r = *L;
        for (i = 1; i < n; i++)
        {
            s = (lnode*)malloc(sizeof(lnode));
            s->data = a[i];
            r->next = s;
            r =s;
        }
    r->next = NULL;
}
void delete(linklist* L,int x)
{
    lnode* p;
    if (*L== NULL) {
        return;
    }
    if((*L)->data == x) 
    {
        p = *L;
        *L = (*L)->next;
        free(p);
        delete(L, x);
    }
    else {
        delete(&(*L)->next, x);
    }
}
void print(linklist* L)
{
    lnode* k=*L;
    while (k)
    {
        printf("%d ", k->data);
        k = k->next;
    }
}
int main()
{
    linklist L;
    buildlinklist(&L);
    delete(&L,3);
    print(&L);
}

2.在带头结点的单链表工中,删除所有值为X的结点,并释放其空间,假设值为X的结点不唯一,试编写算法以实现上述操作(c语言代码实现)

  本题代码如下

void deletex(linklist* L, int x)//删除所有为x的元素
{
	lnode* p = (*L)->next, * pre = *L, * q;
	while (p)
	{
		if (p->data == x)
		{
			q = p;//q指向该结点
			p = p->next;
			pre->next = p;
			free(q);//释放q结点
		}
		else//否则p与pre继续向后遍历
		{
			p = p->next;
			pre = pre->next;
		}
	}
}

完整测试代码

#include<stdio.h>
#include<stdlib.h>
typedef struct lnode
{
	int data;
	struct lnode* next;
}lnode,*linklist;
int n = 6;
int a[6] = { 1,2,3,3,4,5 };
void buildlinklist(linklist *L)//创建链表
{
	*L = (lnode*)malloc(sizeof(lnode));
	(*L)->next = NULL;
	lnode* s = *L, * r = *L;
	int i = 0;
	for (i = 0; i < n; i++)
	{
		s = (lnode*)malloc(sizeof(lnode));
		s->data = a[i];
		s->next = r->next;
		r->next = s;
		r = s;
	}
	r->next = NULL;
}
void deletex(linklist* L, int x)//删除所有为x的元素
{
	lnode* p = (*L)->next, * pre = *L, * q;
	while (p)
	{
		if (p->data == x)
		{
			q = p;//q指向该结点
			p = p->next;
			pre->next = p;
			free(q);//释放q结点
		}
		else//否则p与pre继续向后遍历
		{
			p = p->next;
			pre = pre->next;
		}
	}
}
void print(linklist* L)//输出单链表
{
	lnode* k = (*L)->next;
	while (k)
	{
		printf("%d ", k->data);
		k = k->next;
	}
}
int main()
{
	linklist L;
	buildlinklist(&L);
	print(&L);
	printf("\n");
	deletex(&L, 3);
	print(&L);
	return 0;
}

3.设L为带头结点的单链表,编写算法实现从头到尾反向输出每个结点的值

 本题代码为

void nizhi(linklist* L)//逆置
{
	lnode* p = (*L)->next, * pre = *L;
	lnode* r = p;
	(*L)->next = NULL;
	while (p != NULL)
	{
		p = p->next;
		r->next = (*L)->next;
		(*L)->next = r;
		r = p;
	}
}

完整测试代码

#include<stdio.h>
#include<stdlib.h>
typedef struct lnode
{
	int data;
	struct lnode* next;
}lnode,*linklist;
int n = 4;
int a[4] = { 1,2,3,4 };
void buildlinklist(linklist* L)
{
	*L = (lnode*)malloc(sizeof(lnode));
	(*L)->next = NULL;
	lnode* s = *L, * r = *L;
	int i = 0;
	for (i = 0; i < n; i++)
	{
		s = (lnode*)malloc(sizeof(lnode));
		s->data = a[i];
		s->next = r->next;
		r->next = s;
		r = s;
	}
	r->next = NULL;
}
void nizhi(linklist* L)
{
	lnode* p = (*L)->next, * pre = *L;
	lnode* r = p;
	(*L)->next = NULL;
	while (p != NULL)
	{
		p = p->next;
		r->next = (*L)->next;
		(*L)->next = r;
		r = p;
	}
}
void print(linklist* L)//输出单链表
{
	lnode* p = (*L)->next;
	while (p != NULL)
	{
		printf("%d ", p->data);
		p = p->next;
	}
}
int main()
{
	linklist L;
	buildlinklist(&L);
	printf("原先单链表为:");
	print(&L);
	nizhi(&L);
	printf("\n逆置后的单链表为:");
	print(&L);
	return 0;
}

 4.在带头结点的单链表L中删除一个最小值结点的高效算法(假设最小值唯一) (c语言代码实现)

  本题代码为

void deletemin(linklist* L)//找到最小值并删除
{
	lnode* p = (*L)->next, * pre = *L;
	lnode* s = p,*spre=pre;
	while (p != NULL)//找到最小值
	{
		if (p->data < s->data)
		{
			s = p;
			spre = pre;
		}
		p = p->next;
		pre = pre->next;
	}
	p = s->next;
	spre->next = p;
	free(s);
}

完整测试代码

#include<stdio.h>
#include<stdlib.h>
typedef struct lnode
{
	int data;
	struct lnode* next;
}lnode,*linklist;
int n = 4;
int a[4] = { 1,2,3,4 };
void buildlinklist(linklist* L)
{
	*L = (lnode*)malloc(sizeof(lnode));
	(*L)->next = NULL;
	lnode* s = *L, * r = *L;
	int i = 0;
	for (i = 0; i < n; i++)
	{
		s = (lnode*)malloc(sizeof(lnode));
		s->data = a[i];
		s->next = r->next;
		r->next = s;
		r = s;
	}
	r->next = NULL;
}
void deletemin(linklist* L)
{
	lnode* p = (*L)->next, * pre = *L;
	lnode* s = p,*spre=pre;
	while (p != NULL)//找到最小值
	{
		if (p->data < s->data)
		{
			s = p;
			spre = pre;
		}
		p = p->next;
		pre = pre->next;
	}
	p = s->next;
	spre->next = p;
	free(s);
}
void print(linklist* L)
{
	lnode* p = (*L)->next;
	while (p != NULL)
	{
		printf("%d", p->data);
		p = p->next;
	}
}
int main()
{
	linklist L;
	buildlinklist(&L);
	printf("原始单链表为:");
	print(&L);
	deletemin(&L);
	printf("\n删除最小值后的单链表为:");
	print(&L);
	return 0;
}

5.将带头结点的单链表就地逆置,所谓“就地”是指辅助空间复杂度为O(1) (c语言代码实现)王道数据结构课后代码题p40 5.将带头结点的单链表就地逆置,所谓“就地”是指辅助空间复杂度为O(1) (c语言代码实现)-CSDN博客

 6.有一个带头结点的单链表L,设计一个算法使其元素递增有序 (c语言代码实现)

  这一题其实用到了直接插入排序的思想

视频讲解在这里哦:👇

p40 第6题 王道数据结构课后代码题 c语言代码实现_哔哩哔哩_bilibili

本题代码为

void paixu(linklist* L)//对单链表内的元素排序
{
	lnode* p = (*L)->next;
	lnode* pre = *L;
	lnode* r = p->next;//r保持*p的后继结点指针,保证不断链
	p->next = NULL;//相当于将链断开,构造只含一个数据结点的有序表
	p = r;
	while (p != NULL)
	{
		r = p->next;//保存p的后继指针
		pre = *L;//pre为另一个有序表的工作指针
		while (pre->next != NULL && (pre->next->data < p->data))
			pre = pre->next;//找到下一个结点就大于p的点
		p->next = pre->next;//使p的next指针指向那个点的后继
		pre->next = p;//那个点的next指针指向p
		p = r;//p再指向r,继续工作
	}
}

完整测试代码

#include<stdio.h>
#include<stdlib.h>
typedef struct lnode
{
	int data;
	struct lnode* next;
}lnode,*linklist;
int n = 5;
int a[5] = { 2,1,3,5,4 };
void buildlinklist(linklist* L)//建立单链表
{
	*L = (lnode*)malloc(sizeof(lnode));
	(*L)->next = NULL;
	lnode* s = *L, * r = *L;
	int i = 0;
	for (i = 0; i < n; i++)
	{
		s = (lnode*)malloc(sizeof(lnode));
		s->data = a[i];
		s->next = r->next;
		r->next = s;
		r = s;
	}
	r->next = NULL;
}
void paixu(linklist* L)//对单链表内的元素排序
{
	lnode* p = (*L)->next;
	lnode* pre = *L;
	lnode* r = p->next;//r保持*p的后继结点指针,保证不断链
	p->next = NULL;//相当于将链断开,构造只含一个数据结点的有序表
	p = r;
	while (p != NULL)
	{
		r = p->next;//保存p的后继指针
		pre = *L;//pre为另一个有序表的工作指针
		while (pre->next != NULL && (pre->next->data < p->data))
			pre = pre->next;//找到下一个结点就大于p的点
		p->next = pre->next;//使p的next指针指向那个点的后继
		pre->next = p;//那个点的next指针指向p
		p = r;//p再指向r,继续工作
	}
}
void print(linklist* L)
{
	lnode* q = (*L)->next;
	while (q != NULL)
	{
		printf("%d ", q->data);
		q = q->next;
	}
}
int main()
{
	linklist L;
	buildlinklist(&L);
	printf("原始单链表为:");
	print(&L);
	paixu(&L);
	printf("\n排完序后的单链表为:");
	print(&L);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

努力敲代码的小火龙

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值