C++ 数据结构算法 学习笔记(1)-顺序表

C++ 数据结构算法 学习笔记(1)-顺序表

需求设计

“我要看小星星!”,小芳轻轻的对程序员男友 Jack 说。

“亲爱的,现在是冬天,哪里有小星星耶?” “我不,我就要嘛!” 看着可爱带着小小野蛮的女友,Jack 沉思了一会,说了一句,“好吧!” 默默的回到了电脑前… …

一个小时后,做出来如下的效果:
在这里插入图片描述

如上实现代码为:

#include "self_write_star.h"

void init_star(struct STAR& star)
{	
	int rgb = 0;
	star.x_axis = rand() % SCREEN_WIDTH;
	star.y_axis = rand() % SCREEN_HEIGHT;
	star.radius = 1 + (rand() % RADIUS_MAX);
	star.step = 1 + (rand() % STEP_MAX);
	rgb = 255 * (star.step+5 / STEP_MAX);
	star.colour = RGB(rgb, rgb, rgb);
	star.stat = LEFT;
}

void move_star(SqList& l,int i)
{
	setfillcolor(BLACK);
	solidcircle(l.elems[i].x_axis, l.elems[i].y_axis, l.elems[i].radius);

	if (l.elems[i].stat == UP)
	{
		l.elems[i].y_axis -= l.elems[i].step;
	}
	else if (l.elems[i].stat == DOWN)
	{
		l.elems[i].y_axis += l.elems[i].step;
	}

	else if (l.elems[i].stat == LEFT)
	{
		l.elems[i].x_axis -= l.elems[i].step;
	}

	else if (l.elems[i].stat == RIGHT)
	{
		l.elems[i].x_axis += l.elems[i].step;
	}
	setfillcolor(l.elems[i].colour);
	solidcircle(l.elems[i].x_axis, l.elems[i].y_axis, l.elems[i].radius);
;
}

int main()
{
	bool quit = false;
	initgraph(SCREEN_WIDTH, SCREEN_HEIGHT);
	struct STAR star;
	SqList StarList;
	initList(StarList);

	for (int i = 0; i < MAX_SIZE; i++)
	{
		init_star(star);
		listAppend(StarList,star);
	}

	for (int i = 0; i < MAX_SIZE; i++)
	{
		setfillcolor(StarList.elems[i].colour);
		solidcircle(StarList.elems[i].x_axis, StarList.elems[i].y_axis, StarList.elems[i].radius);
	}

	while (quit == false)
	{
		for (int i = 0; i < StarList.length; i++)
		{
			move_star(StarList,i);
			if (StarList.elems[i].x_axis < 0 || StarList.elems[i].y_axis < 0)
			{
				listDelete(StarList, i);
			}
		}
		if (StarList.length ==0)
		{
			quit = true;
		}
		printList(StarList);
		Sleep(100);
	}

	system("pause");
	closegraph();
	return 0;
}

如上代码可以直接让"星星" 给以各种形式动起来,但是有一个问题.就是效率极低!!!

就是假设有250个星星在显示在程序里,若星星向上移动的话,要程序更有效率的话应该要让"已移除荧幕的星星"不再继续移动.毕竟我们已经看不见了.这样的话程序效率奖大大提升了!!!\

该怎么做呢? 那就需要用到"顺序表的概念"!

顺序表

顺序表是简单的一种线性结构,逻辑上相邻的数据在计算机内的存储位置也是相邻的,可以 快速定位第几个元素,中间不允许有空值,插入、删除时需要移动大量元素。 顺序表的三个要素:

  • 用 elems 记录存储位置的基地址

  • 分配一段连续的存储空间 size

  • 用 length 记录实际的元素个数,即顺序表的长度
    在这里插入图片描述

顺序表的代码定义:

struct SqlList
{
	int* elems;
	int length;
	int size;
};

这种写法是基础的写法,也就是后续定义的话续写成:

struct SqlList l;

另外 ,也可写成

typedef struct
{
	int* elems;
	int length;
	int size;
}SqList;     

这样的话后续定义会更加简单,只需写成:

SqList l; //无需加上 struct字眼

顺序表的 初始化,添加元素,插入元素,删除元素和顺序表销毁

完整代码实现如下:

#include <iostream>
#include <string>

#define MAX_SIZE	100
using namespace std;

typedef struct
{
	int* elems;
	int length;
	int size;
}SqList;

bool initList(SqList& list)
{
	list.elems = new int[MAX_SIZE];
	if (!list.elems)
	{
		return false;
	}

	list.length = 0;
	list.size = MAX_SIZE;
	return true;
}

bool printList(SqList& list)
{
	cout << "Now printing the element inside the list" << endl;
	for (int i = 0; i < list.length; i++)
	{
		cout<<*(list.elems+i)<< " ";
	}
	cout << "The length of the list is " << list.length << " and its size is: " << list.size << endl;
	return true;
}

bool listAppend(SqList& list, int e)
{
	if (list.length < list.size)
	{

		list.elems[list.length] = e;
		list.length++;
		return true;
	}
	else
	{
		cout << "The element is not able to append inside the list" << endl;
		return false;
	}
}

bool listInsert(SqList& l, int num, int e)
{
	if (l.length == l.size || num<=0 ||num>l.length)
	{
		cout << "The list is full! Not able to insert anymore" << endl;
		return false;
	}
	else
	{
		for (int i = l.length - 1 ; i >= num; i--)
		{
			l.elems[i + 1] = l.elems[i];
		}
		l.elems[num] = e;
		l.length++;
		return true;
	}
}
bool listDelete(SqList& l, int num)
{
	if (num<0 || num>l.length)
	{
		return false;
	}
	if (num == l.length-1)
	{
		l.length--;
		return true;
	}
	else
	{
		for (int i = num; i < l.length-1; i++)
		{
			l.elems[i] = l.elems[i + 1];

		}
		l.length--;
		return true;

	}
}

void listRemove(SqList& l)
{
	if (l.elems)
	{
		delete l.elems;
		l.length = 0;
		l.size = 0;
	}
}


int main()
{
	SqList list1;
	initList(list1);
	int element = 0;
	for (int i = 0; i < 10; i++)
	{
		cout << "Please enter the element to append into the list" << endl;
		cin >> element;
		listAppend(list1, element);
	}
	printList(list1);
	cout << "After insert the list" << endl;
	listInsert(list1, 9, 999);
	printList(list1);
	cout << "After delete the list" << endl;
	listDelete(list1, 10);
	printList(list1);
	system("pause");
	return 0;
}

需求如何加上顺序表以优化需求?

如之前说的,若要让需求代码优化效率的话,我们需要让星星一旦离开荧幕后就直接不再移动.

还未移动出的星星继续移动,这样的话程序负担会大大减低, 效率更高!

所以 浪漫星空的优化代码(加上顺序表) 如下:

Star_program.cpp

#include "_star.h"

void init_star(struct STAR& star)
{	
	int rgb = 0;
	star.x_axis = rand() % SCREEN_WIDTH;
	star.y_axis = rand() % SCREEN_HEIGHT;
	star.radius = 1 + (rand() % RADIUS_MAX);
	star.step = 1 + (rand() % STEP_MAX);
	rgb = 255 * (star.step+5 / STEP_MAX);
	star.colour = RGB(rgb, rgb, rgb);
	star.stat = LEFT;
}

void move_star(SqList& l,int i)
{
	setfillcolor(BLACK);
	solidcircle(l.elems[i].x_axis, l.elems[i].y_axis, l.elems[i].radius);

	if (l.elems[i].stat == UP)
	{
		l.elems[i].y_axis -= l.elems[i].step;
	}
	else if (l.elems[i].stat == DOWN)
	{
		l.elems[i].y_axis += l.elems[i].step;
	}

	else if (l.elems[i].stat == LEFT)
	{
		l.elems[i].x_axis -= l.elems[i].step;
	}

	else if (l.elems[i].stat == RIGHT)
	{
		l.elems[i].x_axis += l.elems[i].step;
	}
	setfillcolor(l.elems[i].colour);
	solidcircle(l.elems[i].x_axis, l.elems[i].y_axis, l.elems[i].radius);
;
}

int main()
{
	bool quit = false;
	initgraph(SCREEN_WIDTH, SCREEN_HEIGHT);
	struct STAR star;
	SqList StarList;
	initList(StarList);

	for (int i = 0; i < MAX_SIZE; i++)
	{
		init_star(star);
		listAppend(StarList,star);
	}

	for (int i = 0; i < MAX_SIZE; i++)
	{
		setfillcolor(StarList.elems[i].colour);
		solidcircle(StarList.elems[i].x_axis, StarList.elems[i].y_axis, StarList.elems[i].radius);
	}

	while (quit == false)
	{
		for (int i = 0; i < StarList.length; i++)
		{
			move_star(StarList,i);
			if (StarList.elems[i].x_axis < 0 || StarList.elems[i].y_axis < 0)
			{
				listDelete(StarList, i);
			}
		}
		if (StarList.length ==0)
		{
			quit = true;
		}
		printList(StarList);
		Sleep(100);
	}

	system("pause");
	closegraph();
	return 0;
}

_star.h

#ifndef _SELF_WRITE_STAR_H__
#define _SELF_WRITE_STAR_H__

#include <iostream>
#include <string>
#include <graphics.h>
#include <Windows.h>

using namespace std;
#define MAX_SIZE	250
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define RADIUS_MAX	3
#define STEP_MAX	5

enum STATUS
{
	STOP = 0,
	UP,
	DOWN,
	LEFT,
	RIGHT,
	RANDOM,
	ALL_STATUS

};

struct STAR
{
	int x_axis ;
	int y_axis ;
	int step ;
	int colour ;
	enum STATUS stat;
	unsigned int radius ;
};

typedef struct
{
	STAR* elems;
	int length;
	int size;
}SqList;

bool initList(SqList& list);
bool printList(SqList& list);
bool listAppend(SqList& list, STAR star);
bool listDelete(SqList& l, int num);
void listRemove(SqList& l);

#endif

star_sql.h

#include <iostream>
#include <string>
#include "_star.h"

using namespace std;

bool initList(SqList& list)
{
	list.elems = new struct STAR[MAX_SIZE];
	if (!list.elems)
	{
		return false;
	}

	list.length = 0;
	list.size = MAX_SIZE;
	return true;
}

bool printList(SqList& list)
{
	cout << "The length of the STAR list is " << list.length << " and its size is: " << list.size << endl;
	for (int i = 0; i < list.length; i++)
	{
		cout << "The " << i << " star have the radius of " << list.elems[i].radius << " at the position of x = " << list.elems[i].x_axis << " and y = " << list.elems[i].y_axis << endl; 
	}
	return true;
}

bool listAppend(SqList& list, STAR star)
{
	if (list.length < list.size)
	{

		list.elems[list.length] = star;
		list.length++;
		return true;
	}
	else
	{
		cout << "The element is not able to append inside the list" << endl;
		return false;
	}
}


bool listDelete(SqList& l, int num)
{
	if (num<0 || num>l.length)
	{
		return false;
	}
	if (num == l.length - 1)
	{
		l.length--;
		return true;
	}
	else
	{
		for (int i = num; i < l.length - 1; i++)
		{
			l.elems[i] = l.elems[i + 1];

		}
		l.length--;
		return true;

	}
}

void listRemove(SqList& l)
{
	if (l.elems)
	{
		delete l.elems;
		l.length = 0;
		l.size = 0;
	}
}

  • 16
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值