#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时可以用循环加上简单的赋值语句实现,需要注意删应该从左向右赋值,增应该从右向左赋值(其实就是内存块存在交叉部分时的整体移动问题)。