动态顺序表的功能实现

        在了解线性结构后我们知道它可分为顺序表链表两种,而顺序表又分为静态顺序表动态顺序表.

静态顺序表和静态通讯录的实现极为相似,但是我们知道静态版本有着明显的缺陷,空间分配太大易造成浪费,太小又不便存储,而动态版本正好可以解决这个问题。

       既然前面提到线性结构的组成,那么我们就在说说链表分为哪些:它可分为单向链表,双向链表,循环链表和双向循环链表,这些我们后期再讨论这些。好了,该回到今天的主题上来了——动态顺序表的实现!

      首先,动态顺序表的功能在头文件中已经全部列出来了,在排序的时候给出了三种方式:冒泡排序,直接插入排序和选择排序。在实现测试函数的时候记得打印菜单中的顺序需要和case语句中的顺序保持一致哦,我在这就栽过跟头。。。还值得注意的是:在我们的测试函数中,应当创建一个结构体变量,然后调用函数的时候把其地址传进去,否则传值的话会有压栈的开销,这样一来时间和空间就都浪费很大了。

下来我们就用代码实现它:

Seqlist.h

#define _CRT_SECURE_NO_WARNINGS 1
#ifndef  _SEQLIST_D_H_
#define  _SEQLIST_D_H_

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

#define DEFAULT_SZ 2
#define INC_SZ 2
typedef int DataType;

typedef struct Seqlist
{
	DataType *data;
	int sz;          //实际容量大小
	int capacity;    
}Seqlist,*pSeqlist;



void PrintSeqlist(pSeqlist pSeq);      //顺序表打印输出
void InitSeqlist(pSeqlist pSeq);       //进行初始化
void DestroySeqlist(pSeqlist pSeq);
void PushBack(pSeqlist pSeq,DataType x);//在顺序表尾部插入元素
void PopBack(pSeqlist pSeq);            //在顺序表尾部删除元素
void PushFront(pSeqlist pSeq,DataType x);//在顺序表头部插入元素
void PopFront(pSeqlist pSeq);            //在顺序表头部删除元素
void Insert(pSeqlist pSeq,int pos,DataType x);//在顺序表指定位置插入元素
void Erase(pSeqlist pSeq,DataType pos);       //在指定位置删除该元素
void Remove(pSeqlist pSeq,DataType x);        //删除指定元素
void RemoveAll(pSeqlist pSeq,DataType x);     //删除所有指定的元素
void BubbleSort(pSeqlist pSeq);              //冒泡排序
void InsertionSort(pSeqlist pSeq);           //直接插入排序
void SelectSort(pSeqlist pSeq);               //选择排序
int BinarySearch(pSeqlist pSeq,DataType x);   //二分查找


#endif


Seqlist.c


#include"Seqlist.h"
void PrintSeqlist(pSeqlist pSeq)     //顺序表打印输出
{
	int i=0;
	for(i=0;i<pSeq->sz;i++)
	{
		printf("%d\n",pSeq->data[i]);
	}
}
void InitSeqlist(pSeqlist pSeq)       //进行初始化
{
	pSeq->data=(DataType *)malloc(DEFAULT_SZ*sizeof(DataType));
	if(pSeq->data==NULL)
	{
		printf("out of memory");
		exit(EXIT_FAILURE);
	}
	pSeq->sz=0;
	pSeq->capacity=0;
	memset(pSeq->data,0,DEFAULT_SZ*sizeof(DataType));
}
void DestroySeqlist(pSeqlist pSeq)
{
	free(pSeq->data);
	pSeq->data=NULL;
	pSeq->capacity=0;
    pSeq->sz=0;

}
void Check_capacity(pSeqlist pSeq)
{
	DataType *tmp=NULL;
	if(pSeq->sz==pSeq->capacity)
	{ 
		tmp=(DataType *)realloc(pSeq->data,(pSeq->capacity+=INC_SZ)*sizeof(DataType));
		if(tmp==NULL)
		{
			printf("out of memmory!");
			exit(EXIT_FAILURE);
		}
		pSeq->data=tmp;
		pSeq->capacity+=INC_SZ;
	}
}
void PushBack(pSeqlist pSeq,DataType x)     //在顺序表尾部插入元素
{
	Check_capacity(pSeq);
	pSeq->data[pSeq->sz]=x;
	pSeq->sz++;
}
void PopBack(pSeqlist pSeq)            //在顺序表尾部删除元素
{
	if(pSeq->sz==0)
	{
		printf("顺序表已空!");
		return;
	}
	pSeq->sz--;

}
void PushFront(pSeqlist pSeq,DataType x)   //在顺序表头部插入元素
{
	int i=0;
	Check_capacity(pSeq);
	for(i=pSeq->sz-1;i>=0;i--)
	{
		pSeq->data[i+1]=pSeq->data[i];
	}
	pSeq->data[0]=x;
	pSeq->sz++;

}
void PopFront(pSeqlist pSeq)            //在顺序表头部删除元素
{
	int i=0;
	if(pSeq->sz==0)
	{
        printf("顺序表已空!");
		return;
	}
	for(i=0;i<pSeq->sz;i++)
	{
		pSeq->data[i]=pSeq->data[i+1];
	}
	pSeq->sz--;
}
void Insert(pSeqlist pSeq,int pos,DataType x)  //在顺序表指定位置插入元素
{
	int i=0;
    Check_capacity(pSeq);
	for(i=pSeq->sz-1;i>=pos;i--)
	{
		pSeq->data[i+1]=pSeq->data[i];
	}
	pSeq->data[pos]=x;
	pSeq->sz++;

}

void Erase(pSeqlist pSeq,DataType pos)      //在顺序表指定位置删除元素
{
	int i=0;
	if((pos<0)&&(pos>pSeq->sz))
	{
		printf("删除位置不合法!");
		return;
	}
	for(i=pos;i<pSeq->sz-1;i++)
	{
		pSeq->data[i]=pSeq->data[i+1];
	}
	pSeq->sz--;
}
void Remove(pSeqlist pSeq,DataType x)        //删除指定元素
{
	int i=0;
	int ret=0;
	ret=BinarySearch(pSeq,x);
	if(ret==-1)
	{
		printf("没有找到该元素!\n");
		return;
	}
	for(i=ret;i<pSeq->sz;i++)
	{
		pSeq->data[i]=pSeq->data[i+1];
	}
	pSeq->sz--;
}
void RemoveAll(pSeqlist pSeq,DataType x)    //删除所有指定的元素
{
	int i=0;
	int ret=0;
	ret=BinarySearch(pSeq,x);
	while(ret<pSeq->sz)
	{
		if(ret==-1)
		{
			printf("没有找到该元素!\n");
			return;
		}
		for(i=ret;i<pSeq->sz;i++)
		{
			pSeq->data[i]=pSeq->data[i+1];
		}
		pSeq->sz--;
		ret++;
	}
}
void BubbleSort(pSeqlist pSeq)              //冒泡排序
{
	int i=0;
	int j=0;
	int m=0;
	DataType tmp=0;
	int k=pSeq->sz-1;
	int flag=0;            //表示有序
	for(i=0;i<pSeq->sz-1;i++)
	{
	    m=0;
		flag=0;
		for(j=0;j<k;j++)
		{
			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=1;
				m=j;                 //记住最后一次交换的位置
			}
		}
		if(flag==0)
		{
			return;
		}
		m=k;                  //将k设置为最后一次交换的位置
	}
}
void InsertionSort(pSeqlist pSeq)           //直接插入排序
{
	int i=0;
	int j=0;
	DataType tmp=0;
	for(i=1;i<pSeq->sz;i++)            //控制插入的位置(假设第一个为有序)
	{
		tmp=pSeq->data[i];
		for(j=i-1;(j>=0)&&(pSeq->data[j]>tmp);j--)//满足取出的值大于这个值才进入循环
		{
			pSeq->data[j+1]=pSeq->data[j];
		}
		pSeq->data[j+1]=tmp;
	}
}
void SelectSort(pSeqlist pSeq)               //选择排序
{
	int i=0;
	int j=0;
	DataType tmp=0;
	int min=0;        //作为最小值的下标
	for(i=0;i<pSeq->sz;i++)
	{
		min=i;         //假设第一个为有序(对升序而言第一个为最小值)
		for(j=i+1;j<pSeq->sz;j++)
		{
			if(pSeq->data[j]<pSeq->data[min])
			{
				min=j;
			}
			if(min!=i)
			{
				tmp=pSeq->data[min];
				pSeq->data[min]=pSeq->data[i];
				pSeq->data[i]=tmp;
			}

		}
	}
}
int BinarySearch(pSeqlist pSeq,DataType x)   //二分查找
{
	int left=0;
	int right=pSeq->sz-1;
	int mid=0;
	mid=(right-left)/2+left;
	while(left<right)
	{
		if(pSeq->data[mid]<x)
		{
			right=mid-1;
		}
		else if(pSeq->data[mid]>x)
		{
			left=mid+1;
		}
		else
			return mid;         //返回要查找值的下标,否则要查找的可能也为-1	
	}
	return -1;
}




test.c


#include "Seqlist.h"
void menu()
{
	printf("******************************************\n");
	printf("***0.exit***************1.PrintSeqlist****\n");
	printf("***2.InitSeqlist********3.PushBack********\n");
	printf("***4.PopBack************5.PushFront*******\n");
	printf("***6.PopFront**********7.Insert***********\n");
	printf("***8.Remove*************9.RemoveAll*******\n");
	printf("***10.BubbleSort******11.InsertionSort****\n");
	printf("***12.SelectSort*****13.BinarySearch******\n");
	printf("******14.DestroySeqlist***15.Erase********\n");
	printf("******************************************\n");
}
void test()
{
	Seqlist Seq ;               //创建一个结构体变量
	DataType x=0;
	int ret=0;
	int pos=0;
	int input=1;
	pSeqlist pSeq = &Seq;
	InitSeqlist(&Seq);
	while(input)
	{
		menu();
		printf("请选择:");
		scanf("%d",&input);
		switch(input)
		{
		case 0:
			exit(1);
			break;
		case 1:
			PrintSeqlist(&Seq);
			break;
		case 2:
			InitSeqlist(&Seq);
			break;
		case 3:
			printf("请输入一个要插入的数:");
			scanf("%d",&x);
			PushBack(&Seq,x);
		    break;
		case 4:
			PopBack(&Seq);
			break;
		case 5:
			printf("请输入一个要插入的数:");
			scanf("%d",&x);
			PushFront(&Seq,x);
			break;
		case 6:
			PopFront(&Seq);
			break;
		case 7:
			printf("请输入一个要插入的数:");
			scanf("%d",&x);
			printf("请选择要插入的位置:");
			scanf("%d",&pos);
			Insert(&Seq,pos,x);
			break;
		case 8:
			printf("请输入要删除的元素:");
			scanf("%d",&x);
			Remove(&Seq,x); 
			break;
		case 9:
			printf("请输入要删除的元素:");
			scanf("%d",&x);
			RemoveAll(&Seq,x);  
			break;
		case 10:
			BubbleSort(&Seq); 
			break;
		case 11:
			InsertionSort(&Seq);
			break;
		case 12:
			SelectSort(&Seq);
			break;
		case 13:
			printf("请输入要查找的数:");
			scanf("%d",&x);
			ret=BinarySearch(&Seq,x);
			if(ret!=-1)
			{
				if(pSeq->data[ret]==x)
				{
					printf("%d\n",x);
					printf("查找成功!\n");
				}
				else
					printf("查找失败!\n");
			}
			if(ret==-1)
			{
				printf("查找失败!\n");
			}
			break;
		case 14:
			DestroySeqlist(&Seq);
			break;
		case 15:
			printf("请输入要删除元素的位置:");
			scanf("%d",x);
			Erase(&Seq,x);
		default:
			printf("输入错误!");
			break;
		}
	}
}
int main()
{
	test();
	system("pause");
	return 0;
}


你可能感兴趣的:(动态顺序表的功能实现)