《啊哈,算法》代码优化

今天是2021.1.27,我在看一本叫做《啊哈,算法》的书,这本书的内容十分的基础且有趣,是一本很好的入门算法书,最近几天我都在看它,并且把书中的代码都敲了敲,发现有些代码有一点问题,在这里我作了一些修改。

第 2 章:栈、队列、链表

第 4 节 链表(P44)

题目:

第一行给出一个整数n,第二行给出n个已经从小到大排好的数,第三行给出需要往这串数中插入的数a,输出仍符合从小到大排列的新的序列。

要求:不使用数组,使用链表

输入样例:

9
2 3 5 8 9 10 18 26 32
6

输出样例:

2 3 5 6 8 9 10 18 26 32

书上的代码

#include <stdio.h> 
#include <stdlib.h> 
//这里创建一个结构体用来表示链表的结点类型
struct node 
{ 
 int data; 
 struct node *next; 
}; 
int main() 
{ 
 struct node *head,*p,*q,*t; 
 int i,n,a; 
 scanf("%d",&n); 
 head = NULL;//头指针初始为空
 for(i=1;i<=n;i++)//循环读入n个数
 { 
 scanf("%d",&a); 
 //动态申请一个空间,用来存放一个结点,并用临时指针p指向这个结点
 p=(struct node *)malloc(sizeof(struct node)); 
 p->data=a;//将数据存储到当前结点的data域中
 p->next=NULL;//设置当前结点的后继指针指向空,也就是当前结点的下一个结点为空
 if(head==NULL) 
 head=p;//如果这是第一个创建的结点,则将头指针指向这个结点
 else 
 q->next=p;//如果不是第一个创建的结点,则将上一个结点的后继指针指向当前结点
 q=p;//指针q也指向当前结点
 } 
 
 scanf("%d",&a);//读入待插入的数
 t=head;//从链表头部开始遍历
 while(t!=NULL)//当没有到达链表尾部的时候循环
 { 
 if(t->next->data > a)//如果当前结点下一个结点的值大于待插入数,将数插入到中间
 { 
 p=(struct node *)malloc(sizeof(struct node));//动态申请一个空间,用来存放新增结点
 p->data=a; 
 p->next=t->next;//新增结点的后继指针指向当前结点的后继指针所指向的结点
 t->next=p;//当前结点的后继指针指向新增结点
 break;//插入完毕退出循环
 } 
 t=t->next;//继续下一个结点
 } 
 //输出链表中的所有数
 t=head; 
 while(t!=NULL) 
 { 
 printf("%d ",t->data); 
 t=t->next;//继续下一个结点
 } 
 getchar();getchar(); 
 return 0; 
}

原代码不足之处:

没有考虑输入的数字为最小/最大的情况

比如:

4
1 2 3 4

5

或者

4
1 2 3 4
0

等情况

我的代码:

#include <stdlib.h>
#include <iostream>
using namespace std;
struct node
{
	int data;
	struct node *next;
};

int main()
{
	struct node *head, *p, *q;
	int n;
	cin >> n;
	int z;
	head = NULL;
	for (int i = 0; i < n; i++)
	{
		cin >> z;
		q = (struct node *)malloc(sizeof(struct node));
		q->data = z;
		q->next = NULL;
		if (head == NULL)
		{
			head = q;
			p = q;
			p->next = NULL;
		}
		else
		{
			p->next = q;
			p = q;
			p->next = NULL;
		}

	}
	p = head;
	cin >> z;
	q = (node *)malloc(sizeof(node));
	q->data = z;
	int flag = 0;
	if (p->data > z)//输入的数最小
	{
		q->next = p;
		head = q;
		flag = 1;
	}
	else
	{
		while (p->next != NULL)
		{
			if (p->next->data >= z)
			{
				q->next = p->next;
				p->next = q;
				flag = 1;
				break;
			}
			p = p->next;
		}
	}
	if (flag==0)//输入的数最大
	{
		p->next = q;
		q->next = NULL;
	}
	p = head;
	while (p != NULL)
	{
		cout << p->data << " ";
		p = p->next;
	}

	system("pause");
	return 0;
}

第 5 节 模拟链表

题目和样例与第4节相同,只不过这次要求用模拟链表的方式编写代码。

书本代码:

#include <stdio.h> 
int main() 
{ 
 int data[101],right[101];
 int i,n,t,len; 
 //读入已有的数 
 scanf("%d",&n); 
 for(i=1;i<=n;i++) 
 scanf("%d",&data[i]); 
 len=n; 
 //初始化数组right 
 for(i=1;i<=n;i++) 
 { 
 if(i!=n) 
 right[i]=i+1; 
 else 
 right[i]=0; 
 } 
 //直接在数组data的末尾增加一个数 
 len++; 
 scanf("%d",&data[len]); 
 
 //从链表的头部开始遍历 
 t=1; 
 while(t!=0) 
 { 
 if(data[right[t]]>data[len])//如果当前结点下一个结点的值大于待插入数,将数插入到中间 
 { 
 right[len]=right[t];//新插入数的下一个结点标号等于当前结点的下一个结点编号 
 right[t]=len;//当前结点的下一个结点编号就是新插入数的编号 
 break;//插入完成跳出循环 
 } 
 t=right[t]; 
 } 
 //输出链表中所有的数 
 t=1; 
 while(t!=0) 
 { 
 printf("%d ",data[t]); 
 t=right[t]; 
 }
 getchar(); 
 getchar(); 
 return 0; 
}

不足:

和第4节一样,没考虑输入的数据位于首尾的情况。

我的代码:

#include <iostream>
using namespace std;
int main()
{
	int data[100], right[100];
	int n;
	cin >> n;
	int i, flag = 0;
	for (i = 0; i < n; i++)
	{
		cin >> data[i];
		right[i] = i + 1;
	}
	right[i-1] = -1;
	cin >> data[n];
	if (data[n] <= data[0])
	{
		swap(data[n], data[0]);
		right[n] = n;
		swap(right[n], right[0]);
		flag = 1;
	}
	else 
	{
		i = 0;
		while(right[i]!=-1)
		{
			if (data[n] < data[right[i]])
			{
				right[n] = right[i];
				right[i] = n;	
				flag = 1;
				break;
			}
			i = right[i];
		}
	}
	if (flag==0)
	{
		right[i] = n;
		right[n] = -1;
	}
	i = 0;
	while (right[i]!= -1)
	{
		cout << data[i] << " ";
		i = right[i];
	} 
	cout << data[i];
	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值