BasicArray.cRUN

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

/*
线性表
1.固定长度数组,无封装,需要保存长度
2.插入,删除
3.排序

基本用法
1. 涉及增加删除数据的函数
int Fun(MyTypeList myTypelist, int len);
2. 其它函数
void Fun(MyTypeList myTypelist, int len);
*/

struct Info
{
	char	name[16];
	int		value;
};
//typedef的用法,让类型本身有描述性
typedef struct Info MyType;
//以下用MyType类型,这样更换MyType类型时,后续代码不用大的变化!

#define MAX_LEN  1024
//MyTypeList实际上就是struct Info*
typedef MyType* MyTypeList; 

//输入输出
int Input(MyTypeList myTypeList, int len);
int LoadList(MyTypeList myTypeList, int len, const char* filename);
void PrintList(const MyTypeList myTypeList, int len);
void SaveList(const MyTypeList myTypeList, int len, const char *filename);

//排序
void SortBubble_NameGreat(MyTypeList myTypeList, int len);
void SortBubble_ValueLess(MyTypeList myTypeList, int len);

//插入删除
int PushBack(MyTypeList myTypeList, int len, MyType data);
int Remove_Index(MyTypeList myTypeList, int len, int index);
int Remove_Data(MyTypeList myTypeList, int len, MyType data);

//查找
MyType* Find(MyTypeList myTypeList, int len, MyType data);

//键盘输入测试
void Test_Input()
{
	MyType mylist[MAX_LEN];
	int len = 0;
	len = Input(mylist, len);

	PrintList(mylist, len);
}

//文件读入测试
void Test_Load()
{
	MyType mylist[MAX_LEN];
	int len = 0;
	len = LoadList(mylist, len, "list.txt");

	PrintList(mylist, len);
}

int main()
{
	//Test_Input();
	//Test_Load();

	MyType mylist[MAX_LEN];
	int len = 0;

	MyType arr[] = { {"A1", 5}, {"A3", 4}, {"A2", 4}, {"A5", 3}, {"A4", 1} };
	for (int i = 0; i < sizeof(arr) / sizeof(MyType); i++)
	{
		MyType data = arr[i];
		len = PushBack(mylist, len, data);
	}
	PrintList(mylist, len);

	//Name由大到小
	SortBubble_NameGreat(mylist, len);
	PrintList(mylist, len);

	{
		MyType data = {"Test", 2};
		MyType* pData1 = Find(mylist, len, data);
		if (pData1)
		{//找到
			pData1->value = 22;
		}
		PrintList(mylist, len);
	}

	//由小到大排序
	SortBubble_ValueLess(mylist, len);
	PrintList(mylist, len);

	{
		MyType data = { "Test", 2 };
		len = Remove_Data(mylist, len, data);
		PrintList(mylist, len);
	}

	SaveList(mylist, len, "test.txt");
	return 0;
}


//从键盘输入
int Input(MyTypeList myTypeList, int len)
{
	int cnt;
	int n;
	cnt = scanf("%d", &n);
	for (int i = 0; i < n; i++)
	{
		MyType data;
		cnt = scanf("%s%d", data.name, &data.value);

		len = PushBack(myTypeList, len, data);
	}
	return len;
}


//从文件读入
int LoadList(MyTypeList myTypeList, int len, const char *filename)
{
	int cnt;

	FILE* fp = fopen(filename, "rt");
	
	//表头部分,如果存在

	//数据部分
	while (!feof(fp))
	{
		MyType data;
		cnt = fscanf(fp, "%s%d", data.name, &data.value);

		len = PushBack(myTypeList, len, data);
	}
	fclose(fp);

	return len;
}


//输出到屏幕
void PrintList(const MyTypeList myTypeList, int len)
{
	for (int i = 0; i < len; i++)
	{
		printf("%s %d", myTypeList[i].name, myTypeList[i].value);
		if (i == len - 1)
			printf("\n");
		else
			printf("\t");
	}
}


//保存到文件
void SaveList(const MyTypeList myTypeList, int len, const char* filename)
{
	FILE* fp = fopen(filename, "W+t");
	for (int i = 0; i < len; i++)
	{
		fprintf(fp, "%s %d", myTypeList[i].name, myTypeList[i].value);
		if (i == len - 1)
			fprintf(fp, "\n");
		else
			fprintf(fp, "\t");
	}
	fclose(fp);
}


//线性表表尾插入数据
int PushBack(MyTypeList myTypeList, int len, MyType data)
{
	if (len + 1 >= MAX_LEN)
	{//超出容量
		return len;
	}

	if (myTypeList)
	{
		myTypeList[len] = data;
		len++;
	}

	return len;
}


//线性表指定位置删除数据
int Remove_Index(MyTypeList myTypeList, int len, int index)
{
	if (index < 0 || index >= len)//判断下标
		return len;

	for (int i = index; i < len - 1; i++)
	{
		myTypeList[i] = myTypeList[i + 1];
	}
	len--;

	return len;
}


//线性表删除指定数据
int Remove_Data(MyTypeList myTypeList, int len, MyType data)
{
	for (int i = 0; i < len; i++)
	{
		if (myTypeList[i].value == data.value && strcmp(myTypeList[i].name, data.name) == 0)
		{//找到,删除(实际上是移动后面的数据)

			for (int k = i; k < len - 1; k++)
			{
				myTypeList[k] = myTypeList[k + 1];
			}
			len--;

			break;
		}
	}

	return len;
}


//冒泡排序, 按照value由小到大排列
//顺序:(value左<右), 如果(value左==右)则(name左<右)
void SortBubble_ValueLess(MyTypeList myTypeList, int len)
{
	for (int i = 0; i < len - 1; i++)
	{//n-1轮处理
		// Last i elements are already in place
		int bChanged = 0;
		for (int j = 0; j < len - i - 1; j++)
		{
			//(value左>右) 或者 (value左==右 && name左>右)
			if ((myTypeList[j].value > myTypeList[j + 1].value) ||
				(myTypeList[j].value == myTypeList[j + 1].value && strcmp(myTypeList[j].name, myTypeList[j + 1].name) > 0)
				)
			{//相邻元素逆序,进行交换
				MyType tmp = myTypeList[j + 1];
				myTypeList[j + 1] = myTypeList[j];
				myTypeList[j] = tmp;

				bChanged = 1;
			}
		}
		if (!bChanged)
		{//没有出现位置调整的情况,也就是说,数组已经有序
			return;
		}
	}
}


//冒泡排序, 按照Name由字母序
//顺序:(name左>右), 如果(name左==右)则(value左>右)
void SortBubble_NameGreat(MyTypeList myTypeList, int len)
{
	for (int i = 0; i < len - 1; i++)
	{//n-1轮处理
		// Last i elements are already in place
		int bChanged = 0;
		for (int j = 0; j < len - i - 1; j++)
		{
			//(name左<右) 或者 (name左==右 && value左<右),则交换
			if ((strcmp(myTypeList[j].name, myTypeList[j + 1].name) < 0) ||
				(strcmp(myTypeList[j].name, myTypeList[j + 1].name) ==0 && myTypeList[j].value > myTypeList[j + 1].value)
				)
			{//相邻元素逆序,进行交换
				MyType tmp = myTypeList[j + 1];
				myTypeList[j + 1] = myTypeList[j];
				myTypeList[j] = tmp;

				bChanged = 1;
			}
		}
		if (!bChanged)
		{//没有出现位置调整的情况,也就是说,数组已经有序
			return;
		}
	}
}


//顺序查找
MyType* Find(MyTypeList myTypeList, int len, MyType data)
{
	for (int i = 0; i < len; i++)
	{
		if (myTypeList[i].value == data.value && strcmp(myTypeList[i].name, data.name) == 0)
			return &myTypeList[i];
	}

	return 0;
}