数据结构学习 顺序表C语言实现

#pragma once

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

//默认表元素个数
#define N 100

typedef int data_t;

typedef struct
{
	data_t data[N];
	int last;//最后一个成员的位置

}sqlist, *p_sqlist;

//创建顺序表
p_sqlist list_creat();

//释放空间
int list_free(p_sqlist p);

//线性表置空,成功返回0,失败返回-1
int list_clear(p_sqlist p);

//判断是否为空,不为空返回0,为空返回-1
int list_empty(p_sqlist p);

//求长度,返回长度
int list_length(p_sqlist p);

//删除第i个元素,成功返回0,失败返回-1
int list_delete(p_sqlist p, int i);

//在第i位插入新元素,成功返回0,失败返回-1
int list_insert(p_sqlist p, int i, const data_t* sour);

//查找元素,成功返回下标,失败返回-1
int list_find(p_sqlist p, const data_t* sour);

//打印元素类型为int的顺序表
void list_show(const p_sqlist p);

//顺序表合并
p_sqlist list_merge(p_sqlist p1, const p_sqlist p2);

//删除相同元素
int list_duplicate(p_sqlist p);

头文件SquenceTable.h,用于声明函数,定义结构体。

#include "SequenceTable.h"

p_sqlist list_creat()
{
	p_sqlist L;
	L = (p_sqlist)malloc(sizeof(sqlist));
	if (L == NULL)
	{
		printf("Error.\n");
		return NULL;
	}
	memset(L, 0, sizeof(sqlist));
	L->last = -1;
	return L;
}

int list_clear(p_sqlist p)
{
	if (p == NULL)
	{
		printf("Error.\n");
		return -1;
	}
	memset(p, 0, sizeof(sqlist));
	p->last = -1;
	return 0;
}

int list_empty(p_sqlist p)
{
	if (p == NULL)
	{
		printf("Error.\n");
		return -1;
	}
	if (p->last == -1)
	{
		printf("Empty list.\n");
		return -1;
	}
	else
	{
		return 0;
	}
}

int list_length(p_sqlist p)
{
	if (p == NULL)
	{
		printf("Error.\n");
		return -1;
	}
	return (p->last) + 1;
}

int list_delete(p_sqlist p, int i)
{
	if (p == NULL)
	{
		printf("Error.\n");
		return -1;
	}
	if (p->last == -1)
	{
		//空表
		printf("Empty list.\n");
		return -1;
	}
	if (i >= 0 && i <= (p->last + 1))
	{
		memmove(&(p->data[i - 1]), &(p->data[i]), (N - i) * sizeof(data_t));
		memset(&(p->data[p->last]), 0, sizeof(data_t));
		(p->last)--;
		return 0;
	}
	else
	{
		//输入不合法
		printf("Error.\n");
		return -1;
	}
}

int list_insert(p_sqlist p, int i, const data_t* sour)
{
	if (p == NULL)
	{
		printf("Error.\n");
		return -1;
	}
	if (p->last == N - 1)
	{
		//表已满
		return -1;
	}
	if (i >= 0 && i <= (p->last + 1))
	{
		memmove(&(p->data[i + 1]), &(p->data[i]), (N - i - 1) * sizeof(data_t));
		p->data[i] = *sour;
		(p->last)++;
		return 0;
	}
	else
	{
		//输入不合法
		printf("Error.\n");
		return -1;
	}

}

int list_find(const p_sqlist p, const data_t* sour)
{
	if (p == NULL)
	{
		printf("Error.\n");
		return -1;
	}
	for (int i = 0; i < p->last + 1; i++)
	{
		if(memcmp(&(p->data[i]), sour, sizeof(data_t)) == 0)
			return i;
	}
	return -1;
}

int list_free(p_sqlist p)
{
	if (p == NULL)
	{
		printf("Error.\n");
		return -1;
	}
	free(p);
	p = NULL;
	return 0;
}

void list_show(const p_sqlist p)
{
	for (int i = 0; i < (p->last + 1); i++)
	{
		printf("%d ", p->data[i]);
	}
	printf("\n");
}

p_sqlist list_merge(p_sqlist p1, const p_sqlist p2)
{
	if (p1 == NULL || p2 == NULL)
	{
		printf("Error.\n");
		return NULL;
	}
	if ((p1->last + p2->last) >= N - 2)
	{
		//合并后表太大
		printf("Error.\n");
		return NULL;
	}
	int ret = 0;
	int i = 0;
	while (i <= p2->last)
	{
		ret = list_find(p1, &(p2->data[i]));
		if (ret == -1)
		{
			list_insert(p1, p1->last + 1, &(p2->data[i]));
		}
		i++;
	}
	return p1;
}

int list_duplicate(p_sqlist p)
{
	if (p == NULL)
	{
		printf("Error.\n");
		return NULL;
	}
	int j = 0;
	while (j < p->last + 1)
	{
		for (int i = j + 1; i < p->last + 1; i++)
		{
			if(memcmp(&(p->data[j]), &(p->data[i]), sizeof(data_t)) == 0)
			{
				list_delete(p, i);
			}
		}
		j++;
	}
	return 0;
}

 SquenceTable.c,实现函数功能,增删查改等。

#include "SequenceTable.h"

int main()
{
	int val = 11;
	int* pt = &val;
	p_sqlist p = NULL;
	p = list_creat();
	list_length(p);
	for (size_t i = 0; i < 25; i++)
	{
		list_insert(p, i, &i);
		list_insert(p, i+1, &i);
		i++;
	}

	//p_sqlist p1 = list_creat();
	//for (size_t i = 13; i < 95; i++)
	//{
	//	list_insert(p1, i-13, &i);
	//}

//	list_insert(p, 2, pt);
//	list_delete(p, list_find(p, &val));
//	list_clear(p);
	list_show(p);
	//list_show(p1);
	printf("###############\n");
//	list_merge(p, p1);
	list_duplicate(p);
	list_show(p);
//	list_show(p1);

	list_free(p);
	return 0;
}

 main.c,测试函数功能。

        顺序表相对简单,学完才知道之前通讯录使用的就是顺序表。删和增的功能使用了内存函数,但数据类型是int时可以用循环加上简单的赋值语句实现,需要注意删应该从左向右赋值,增应该从右向左赋值(其实就是内存块存在交叉部分时的整体移动问题)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值