顺序表(动态开辟内存)

原创 2016年06月01日 21:31:28

# 动态顺序表


@ 相关文章: 静态顺序表;  

@相关链接: 冒泡,直接插入,选择,排序的实现

@文中关于三种排序的调用,运用了函数指针数组;函数指针数组博客链接


@ 自定义头文件“pSeqList.h”

#ifndef _SEQLIST_H__//防止头文件重定义
#define _SEQLIST_H__

#define _CRT_SECURE_NO_WARNINGS 1//消除scanf的警告
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define MAX 2
enum Select
{
	EXIT,
	INSERT ,
	SORT,
	BINARYSEARCH,
	REMOVE,
	PUSHFRONT ,
	PUSHBACK ,
	POPBACK,
	POPFRONT,
	PRINTSEQLIST
};
typedef int DataType;//数据可以是int也可以是char,为方便修改可以在这里进行类型重定义
                     //注意的是,代码里的%d,%c接收和输出要与类型一致;
typedef struct SepLish
{
	DataType *Data;//最大容量预定义为MAX = 100;
	int sz;
	int capacity;
}SeList,*pSepList;

void InitSeqList(pSepList pSeq);//初始化

void PrintSeqList(pSepList pSeq);//打印

void PopFront(pSepList pSeq);//头删
void PopBack(pSepList pSeq);//投插
void BubbleSort(pSepList pSeq);//冒泡排序
void InsertionSort(pSepList pSeq);//插入排序;
void SelectSort(pSepList pSeq);//选择排序;
void PushBack(pSepList pSeq, DataType x);//尾插
void PushFront(pSepList pSeq,DataType x);//头删
void BinarySerach(pSepList pSeq,DataType x);//查找
void _Remove(pSepList pSeq,DataType x);//删除
void RemoveAll(pSepList pSeq,DataType x);//删除所有的指定元素;
void Insert(pSepList pSeq,int pos,DataType x);//插入
void Exit(pSepList pSeq);

void (*array [3])(pSepList pSeq);


void test();

#endif  //_SEQLIST_H__


@ 函数功能实现

#include"SeqList.h"

void Judge_full(pSepList pSeq)//包装一个公用函数;
{
	if(pSeq ->sz == pSeq ->capacity )
	{
		DataType* tmp = NULL;

		tmp = (DataType*)realloc(pSeq->Data ,(pSeq ->capacity +1)*sizeof(DataType));
	    if(tmp == NULL)
	    {
		  printf("扩容失败\n");
		  return ;
	    }
		pSeq->Data = tmp;
	    pSeq->capacity +=1;
	}
}//判断容量是否已满


void PrintSeqList(pSepList pSeq)//打印所有数据;
{
	int i = 0;
	printf("*************************************************\n\n");
	printf("以下为所有数据:> ");
	for(;i < pSeq ->sz ;i++)
	{
		printf("%d ",pSeq ->Data[i]);
	}
	printf("\n\n*************************************************\n");
}//打印

void InitSeqList(pSepList pSeq)//初始化顺序表;
{
	pSeq->Data = (DataType*)malloc(MAX*sizeof(DataType));
	if(pSeq->Data == NULL)
	{
		printf("make memery break!\n");
		return ;
	}
	memset(pSeq->Data ,0,MAX*sizeof(DataType));
	pSeq->sz = 0;
	pSeq->capacity = MAX;
}//初始化

void PushBack(pSepList pSeq, DataType x)//从最后加入成员
{
	Judge_full(pSeq);
	pSeq ->Data [pSeq ->sz++] = x;

	printf("\n^^^^^^添加成功^*^^^^^^^^^\n\n");
}//尾插

void PopBack(pSepList pSeq)//从最后删除一个成员
{
	pSeq ->sz --;
	printf("\n*** 删除成功 ***\n\n");
}//尾删

void PushFront(pSepList pSeq,DataType x)//在第一个位置加入元素;
{
	int i = pSeq ->sz;
	Judge_full(pSeq);
	
	for(;i >=0; i--)
	{
		pSeq ->Data [i] = pSeq ->Data [i - 1];//在空间足够的情况下,所有元素向后挪动一个位置
	}
	pSeq ->Data [0] = x;
	printf("\n^^^^^^添加成功^*^^^^^^^^^\n\n");
	pSeq ->sz ++;
}//头插

void PopFront(pSepList pSeq)//删除第一个位置的元素;
{
	int i = 0;
	if(pSeq ->sz == 1)//只有一个元素的话直接将sz置为0即可;
	{
		pSeq ->sz = 0;
	}
	else
	{
		for(i = 0; i < pSeq ->sz ; i++)
		{
			pSeq ->Data [i] = pSeq ->Data [i + 1];//从第二个人元素开始,所有元素向前挪动一个位置;
		}
	}
	printf("\n*** 删除成功 ***\n\n");
	pSeq ->sz --;
}//头删

void Insert(pSepList pSeq,int pos,DataType x)//指定位置加入一个成员;
{
	int i = pSeq ->sz ;
	Judge_full(pSeq);

	if(pos > i+1)//注意要对指定为值进行判断,该位置是否合理;
	{
		printf("选择位置有误\n");
		return ;
	}

	
	for(;i >=pos; i--)
	{
		pSeq ->Data [i] = pSeq ->Data [i - 1];//挪动下表为pos开始往后所有元素;
	}
	pSeq ->Data [pos - 1] = x;
	printf("\n^^^^^^添加成功^*^^^^^^^^^\n\n");
	pSeq ->sz ++;
}//插入

int find_X(pSepList pSeq,DataType x)//包装的公用查找函数;
{
	int i = 0;
	/* 这里其实有个问题我没处理,在删除那里也会出现,就是有重复元素的情况,
	有兴趣的同学可以补全一下;
	*/
	for(; i < pSeq ->sz ; i++)
	{
		if(pSeq ->Data [i] == x)
			return i;
	}
	return -1;
}//单独包装的查找函数

void BinarySerach(pSepList pSeq,DataType x)//查找指定成员;
{
	int index = find_X(pSeq,x);//直接调用公用查找函数

	if(index >= 0)
	 printf("\n***查找到的结果:%d ***\n\n",pSeq->Data [index]);
	else
		printf("\n***没找到该内容***\n\n");
}//查找

void _Remove(pSepList pSeq,DataType x)
{
	int i = 0;
	int index = 0;

	index = find_X(pSeq,x);

	if(index < 0)
		printf("无此成员\n");
	else
	{
		if(pSeq->sz == 1)
		{
			pSeq->sz = 0;
		}
		else
		{
		for(i = index; i<pSeq->sz - 1 ; i++)
		{
			pSeq->Data [i] = pSeq->Data [i+1];
		}
		pSeq->sz --;
		}
	}
}//删除单个指定元素;

void RemoveAll(pSepList pSeq,DataType x)//删除所有的指定元素;
{
	//有兴趣的同学可以在加一个功能,删除指定位置的元素,更为合理;
	int i = 0;
	int j = 0;

	if(pSeq ->sz == 1)
		pSeq ->sz  = 0;
	else
	{
		for(j = 0; j < pSeq ->sz ; )
			if(pSeq ->Data [j] == x)
			{	
				if(pSeq->sz == 1)
				{
					pSeq->sz = 0;
					return;
				}

				for(i = j; i < pSeq ->sz-1 ; i++)
				{
					pSeq ->Data [i] = pSeq ->Data [i + 1];
				}
				pSeq ->sz --;
			}
			else
				j++;
	printf("\n*** 删除成功 ***\n\n");
	}

}//删除

void BubbleSort(pSepList pSeq)//冒泡排序所有元素
{
	int i = 0;
	int j = 0;
	int k = pSeq ->sz -1;
	int m = 0;

	for(i = 0; i < pSeq ->sz  -1; i++)
	{
		int flag = 1;
		m = 0;
		k =  pSeq->sz  - i - 1;
		for(j = 0; j < k; j++)
		{
			int tmp = 0;
			if(pSeq->Data [j] > pSeq ->Data [j+1] )
			{
				tmp = pSeq ->Data [j];
				pSeq ->Data [j] = pSeq ->Data [j+1];
				pSeq ->Data [j+1] = tmp;
				flag = 0;
				m = j;
			}
		}
		if(flag == 1)
			return ;
		k = m;
	}
}//冒泡

void InsertionSort(pSepList pSeq)
{
	int i = 0;
	int j = 0;
	int k = 0;

	if(pSeq->sz <= 1)
		return ;
	for(i = 1; i < pSeq->sz ; i++)
	{
		DataType tmp = pSeq ->Data [i];

		for(j = i - 1; j >= 0; j--)
		{
			if(pSeq ->Data [i]>=pSeq ->Data [j])
			break;
		}
		for(k = i - 1; k>j; k--)
			pSeq ->Data [k+1] = pSeq ->Data [k];
		pSeq ->Data [j+1] = tmp;
	}
}//直接插入排序;


void SelectSort(pSepList pSeq)
{
	int i = 0;
	int j = 0;

	DataType  min = 0;

	if(pSeq->sz == 1)
		return ;

	for(i = 0; i < pSeq ->sz ; i++)
	{
		int k = 0;
		min = pSeq ->Data [i];
		
		for(j = i+1; j < pSeq ->sz ; j++)
		{
			if(pSeq ->Data [j] < min)
			{
				min = pSeq ->Data [j];
				k = j;
			}

		}
		if(min!= pSeq ->Data [i])
		{
			pSeq ->Data [k] = pSeq ->Data [i];
			pSeq ->Data [i] = min;
		}
	}
}//选择排序;

void (*array [3])(pSepList pSeq) = {BubbleSort,InsertionSort,SelectSort};

void Exit(pSepList pSeq)//退出
{
	free(pSeq->Data);
	pSeq->Data = NULL;
	exit(0);
}




@ 测试代码部分

#include"SeqList.h"

void Print_Select()//打印菜单
{
	    printf("    *******功能表*******\n");
		printf("*******1.插入数据         *******\n");
		printf("*******2.排序             *******\n");
		printf("*******3.查找             *******\n");
		printf("*******4.删除             *******\n");
		printf("*******5.顶部插入数据     *******\n");
		printf("*******6.尾部插入数据     *******\n");
		printf("*******7.尾部部删除数据   *******\n");
		printf("*******8.顶部删除数据     *******\n");
		printf("*******9.打印所有数据     *******\n");
		printf("*******10.清空所有数据    *******\n");
		printf("*******11.清空所有的数据x *******\n");
		printf("*******0.退出             *******\n");
		printf("*********************************\n");
}


void test()//接下来就是选择了
{
	int select = 0;
	SeList pon;
	InitSeqList(&pon);
	
	while(1)
	{
	Print_Select();
	printf("\n***当前有成员:%d 个***\n\n",pon.sz );
	printf("请输入选择:> ");
	scanf("%d",&select );

	if(select >= 0 || select <= 10)
	{
		int data = 0;
		int pos = 0;
		switch(select)
		{
		case INSERT:
			printf("请输入要加入成员的位置:>");
			scanf("%d",&pos);
			printf("请输入要加入的成员:>");
			scanf("%d",&data);
			Insert(&pon,pos,data);
			break;
		case SORT:
			printf("请选择排序方法:1:冒泡 2:直接插入 3:选择\n");
			scanf("%d",&data);
			array[data-1](&pon);
			break;
		case BINARYSEARCH:
			printf("请输入需要查找的成员:> ");
			scanf("%d",&data);
			BinarySerach (&pon,data);
			break;
		case REMOVE:
			printf("请输入需要删除的成员:> ");
			scanf("%d",&data);
			_Remove(&pon,data);
			break;
		case PUSHFRONT:
			printf("请输入需要加入的成员:> ");
			scanf("%d",&data);
			PushFront(&pon,data);
			break;
		case PUSHBACK:
			printf("请输入需要加入的成员:> ");
			scanf("%d",&data);
			PushBack (&pon,data);
			break;
		case POPBACK:
			PopBack (&pon);
			break;
		case POPFRONT:
			PopFront (&pon);
			break;
		case PRINTSEQLIST :
			PrintSeqList(&pon);
			break;
		case 10:
			pon.sz  = 0;
			break;
		case 11:
			printf("请输入需要删除的成员:> ");
			scanf("%d",&data);
			RemoveAll (&pon,data);
			break;
		case EXIT:
			Exit(&pon);
			break;
		default:
			printf("\n*** 输入选项有误: >_< ***\n\n");
			break;
		}
	}
	else
		printf("\n*** 输入选项有误: >_< ***\n\n");
	}
}


int main()
{
	test();
	system("pause");
	return 0;
}



敲了大半天,真的挺累!


版权声明:本文为博主原创文章,未经博主允许不得转载。

线性表的动态分配顺序存储结构

线性表 定义:是最常用的,也是最简单的数据结构,是长度为n个数据元素的有序的序列。 含有大量记录的线性表叫文件 记录:稍微复杂的线性表里,数据元素为若干个数据项组成,这时...

动态顺序表(可扩容)的基本操作

头文件:#define _CRT_SECURE_NO_WARNINGS 1 #ifndef _STATICSEQLIST_H__ #define _STATICSEQLIST_H__#include ...

【数据结构】关于数据结构顺序表动态内存开辟的介绍

数据结构中,线性表的顺序存储结构就是,把线性表中的所有元素按照其逻辑顺序依次存储在计算机存储器中指定存储位置开始的一块连续的存储空间中。 因此,线性表的顺序存储结构是利用数组来实现的,数组的基本类型...
  • Qregi
  • Qregi
  • 2017年12月13日 17:26
  • 4

动态顺序表(可分配内存空间)

前几天写了一个静态顺序表,但是觉得一开始开辟很大一部分空间却不一定可以完全用得上,会造成很大的内存浪费,于是写了一个可以自动开辟内存空间的动态顺序表作为改进。 "DynamicSeqllist.h"...

动态数组,数组初始化,数组内存释放,向数组中添加一个元素,向数组中添加多个元素,数组打印,顺序查找,二分查找,查找数组并返回地址,冒泡排序,改变数组中某个元素的值,删除一个数值,删除所有,查找含有

1定义接口: Num.h #ifndef _NUM_H_ #define _NUM_H_   #include #include   /**********************...

Day17、链式存储结构动态分配内存、栈的顺序存储结构和链式存储结构

数组是一串连续的存储空间,数组名对应的是存储空间的首地址,比较安全、 指针有多样性,不安全,但是灵活,容易出现野指针 数组指针的本质是数组,数组里的元素是指针     链式物理结构中每个有效结点都应该...

动态顺序表

  • 2012年12月10日 22:12
  • 7KB
  • 下载

动态分配的顺序线性表的十五种操作—C语言实现

线性表 定义:是最常用的,也是最简单的数据结构,是长度为n个数据元素的有序的序列。 含有大量记录的线性表叫文件 记录:稍微复杂的线性表里,数据元素为若干个数据项组成,这时把一个数据元...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:顺序表(动态开辟内存)
举报原因:
原因补充:

(最多只允许输入30个字)