数组是一种线性数据结构,而这种结构称之为顺序表。
编写过程
1.在尾部添加元素(PushBack)
test.c
#include "SeqList.h"
void test()
{
SeqList my_list;
InitSeqList(&my_list);//初始化顺序表
PushBack(&my_list, 1);
PushBack(&my_list, 2);
PushBack(&my_list, 3);
PushBack(&my_list, 4);
Display(&my_list);
//打印时候可以不传地址,因为只打印,不会改它,只要拿到里面的数据就可以了。
//形参是实参的临时拷贝,数据sz全部传过去,打印没有任何问题,但这样做不好。
//结构体传参,传地址,不要传变量,因为传变量系统压栈的开销比较大,结构体可能会大。所以传地址比较好。
}
int main()
{
test();
system("pause");
return 0;
}
SeqList.c
#include "SeqList.h"
void InitSeqList(pSeqList ps)
{
ps->sz = 0;
memset(ps->data, 0, sizeof(ps->data));
}
void PushBack(pSeqList ps, DataType d)//在尾部添加元素
{
assert(ps != NULL);
if (ps->sz == MAX)//当元素个数达到最大就不能继续往上添加了
{
return;
}
ps->data[ps->sz] = d;
ps->sz++;//尾部插入元素
}
void Display(const pSeqList ps)
{
int i = 0;
assert(ps != NULL);
for (i = 0; i < ps->sz; i++)
{
printf("%d ", ps->data[i]);
}
printf("\n");
}
2在尾部删除元素(PushBack)
test.c *下面显示新增代码
void test1()
{
SeqList my_list;
InitSeqList(&my_list);//初始化顺序表
PushBack(&my_list, 1);
PushBack(&my_list, 2);
PushBack(&my_list, 3);
PushBack(&my_list, 4);
Display(&my_list);
//打印时候可以不传地址,因为只打印,不会改它,只要拿到里面的数据就可以了。
//形参是实参的临时拷贝,数据sz全部传过去,打印没有任何问题,但这样做不好。
//结构体传参,传地址,不要传变量,因为传变量系统压栈的开销比较大,结构体可能会大。所以传地址比较好。
PopBack(&my_list);
Display(&my_list);
PopBack(&my_list);
Display(&my_list);
PopBack(&my_list);
Display(&my_list);
PopBack(&my_list);
Display(&my_list);
}
int main()
{
test1();
system("pause");
return 0;
}
SeqList.c
void PopBack(pSeqList ps)//在尾部删除元素
{
assert(ps != NULL);
if (ps->sz == 0)//当元素个数为0时就不能继续删除了
{
return;
}
ps->sz--;
}
3.头部插入(PushFront)
如果想在1前面加个5,我先把4向后移,再把3向后移,再把2向后移,再把1向后移.
test.c
void test2()
{
SeqList my_list;
InitSeqList(&my_list);//初始化顺序表
PushFront(&my_list, 1);
PushFront(&my_list, 2);
PushFront(&my_list, 3);
PushFront(&my_list, 4);
Display(&my_list);
}
int main()
{
test2();
system("pause");
return 0;
}
SeqList.c
void PushFront(pSeqList ps, DataType d)//头部插入
{
assert(ps != NULL);
if (ps->sz < MAX)
{
int i = 0;
for (i = ps->sz; i>0; i--)
{
ps->data[i] = ps->data[i - 1];//把元素向后移一个位置
}
ps->data[0] = d;
ps->sz++;
}
//把所有元素向后挪,再把元素插上去
}
SeqList.c(改进部分)
void PushFront(pSeqList ps, DataType d)//头部插入
{
assert(ps != NULL);
if (ps->sz < MAX)
{
int i = 0;
memmove(ps->data+1,ps->data,sizeof(DataType)*(ps->sz));
//memmove(目标,源,字节个数)
//sizeof(DataType)*(ps->sz):该类型的字节数*元素的个数=总字节数
ps->data[0] = d;
ps->sz++;
}
//把所有元素向后挪,再把元素插上去
}
4 头部删除(PopFront)
test.c
void test2()
{
SeqList my_list;
InitSeqList(&my_list);//初始化顺序表
PushFront(&my_list, 1);
PushFront(&my_list, 2);
PushFront(&my_list, 3);
PushFront(&my_list, 4);
Display(&my_list);
PopFront(&my_list);
Display(&my_list);
PopFront(&my_list);
Display(&my_list);
PopFront(&my_list);
Display(&my_list);
PopFront(&my_list);
Display(&my_list);
}
int main()
{
test2();
system("pause");
return 0;
}
SeqList.c
void PopFront(pSeqList ps)//头部删除
{
int i = 0;
assert(ps != NULL);
if (ps->sz == 0)//当元素个数为0时就不能继续删除了
{
return;
}
for (i = 0; i < ps->sz-1; i++)//为了不越界访问
{
ps->data[i] = ps->data[i + 1];
//但还有一个元素不能删
}
ps->sz--;//可以把最后一个元素也删了
}
运行界面
5 查找指定元素(Find)
(见下)
6 指定位置插入(Insert)
test.c
void test3()
{
SeqList my_list;
int pos = 0;
InitSeqList(&my_list);//初始化顺序表
PushFront(&my_list, 1);
PushFront(&my_list, 2);
PushFront(&my_list, 3);
PushFront(&my_list, 4);
PushFront(&my_list, 5);
pos=Find(&my_list,4);
if (pos == -1)
{
printf("要查找的元素不存在\n");
}
else
{
Insert(&my_list, 6, pos);//把6插入pos的位置上
}
Display(&my_list);
}
int main()
{
test3();
system("pause");
return 0;
}
SeqList.c
int Find(pSeqList ps, DataType d)//查找指定元素//int 指的是返回的下标
{
int i = 0;
assert(ps != NULL);
for (i = 0; i < ps->sz ; i++)
{
if (d == ps->data[i])
return i;
}
return -1;
}
void Insert(pSeqList ps, DataType d, int pos)//指定位置插入
{
int i = 0;
assert(ps != NULL);
if (ps->sz == MAX)
{
return;
}
for (i = ps->sz; i > pos; i--)
{
ps->data[i] = ps->data[i - 1];//把元素向后移一个位置
}
ps->data[pos] = d;
ps->sz++;
}
运行界面
test.c
void test4()
{
SeqList my_list;
int pos = 0;
InitSeqList(&my_list);//初始化顺序表
PushFront(&my_list, 1);
PushFront(&my_list, 2);
PushFront(&my_list, 3);
PushFront(&my_list, 4);
PushFront(&my_list, 5);
Display(&my_list);
Remove(&my_list, 3);
Display(&my_list);
}
int main()
{
test4();
system("pause");
return 0;
}
SeqList.c
void Remove(pSeqList ps, DataType d)//删除指定位置元素
{
int pos = 0;
assert(ps != NULL);
pos=Find(ps,d);
if (pos != -1)
{
memmove(ps->data + pos, ps->data + pos + 1, (ps->sz - pos - 1)*sizeof(DataType));
ps->sz--;
}
}
运行界面
test.c
void test5()
{
SeqList my_list;
int pos = 0;
InitSeqList(&my_list);//初始化顺序表
PushFront(&my_list, 1);
PushFront(&my_list, 3);
PushFront(&my_list, 3);
PushFront(&my_list, 2);
PushFront(&my_list, 3);
PushFront(&my_list, 4);
PushFront(&my_list, 3);
PushFront(&my_list, 5);
PushFront(&my_list, 3);
Display(&my_list);
RemoveAll(&my_list, 3);
Display(&my_list);
}
int main()
{
test5();
system("pause");
return 0;
}
SeqList.c
void RemoveAll(pSeqList ps, DataType d)//删除指定所有元素,一个元素可能出现多次,把这个元素都删掉。
{
int pos = 0;
while ((pos = Find(ps,d))!=-1)
{
Remove(ps, d);
}
}
运行界面
9 把顺序表的元素逆序(Reverse)
test.c
void test6()
{
SeqList my_list;
InitSeqList(&my_list);//初始化顺序表
PushFront(&my_list, 1);
PushFront(&my_list, 2);
PushFront(&my_list, 3);
PushFront(&my_list, 4);
PushFront(&my_list, 5);
Display(&my_list);
Reverse(&my_list);
Display(&my_list);
}
int main()
{
test6();
system("pause");
return 0;
}
SeqList.c
void Reverse(pSeqList ps)//把顺序表的元素逆序
{
DataType*left = ps->data;
DataType*right = ps->data+ps->sz-1;
assert(ps != NULL);
while (left < right)//逆序
{
DataType tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
运行界面
test.c
void test7()
{
SeqList my_list;
InitSeqList(&my_list);//初始化顺序表
PushFront(&my_list, 1);
PushFront(&my_list, 2);
PushFront(&my_list, 3);
PushFront(&my_list, 4);
PushFront(&my_list, 5);
Display(&my_list);
Sort(&my_list);
Display(&my_list);
}
int main()
{
test7();
system("pause");
return 0;
}
SeqList.c
void Sort(pSeqList ps)//重新排序
{
int i = 0;
int j = 0;
assert(ps != NULL);
for (i = 0; i < ps->sz - 1; i++)
{
for (j = 0; j < ps->sz - 1 - i; j++)
{
DataType tmp = ps->data[j];
ps->data[j] = ps->data[j + 1];
ps->data[j + 1] = tmp;
}
}
}
11 二分查找(BinarySearch)
test.c
void test7()
{
SeqList my_list;
int pos = 0;
InitSeqList(&my_list);//初始化顺序表
PushFront(&my_list, 1);
PushFront(&my_list, 2);
PushFront(&my_list, 3);
PushFront(&my_list, 4);
PushFront(&my_list, 5);
Display(&my_list);
Sort(&my_list);
Display(&my_list);
pos = BinarySearch(&my_list, 3);
printf("%d\n", pos);
pos = BinarySearch(&my_list, 6);
printf("%d\n", pos);
}
int main()
{
test7();
system("pause");
return 0;
}
SeqList.c
int BinarySearch(pSeqList ps, DataType d)//二分查找
{
int left = 0;
int right = ps->sz - 1;
assert(ps != NULL);
while (left<=right)
{
int mid = left + ((right - left) >> 1);
if (d == ps->data[mid])
{
return mid;
}
else if (d < ps->data[mid])
{
right = mid - 1;
}
else
{
left = mid + 1;
}
}
}
运行界面
SeqList.h
#define _CRT_SECURE_NO_WARNINGS 1
#ifndef __SEQLIST_H__
#define __SEQLIST_H__
#include <stdio.h>
#include <assert.h>
#include <string.h>
#define MAX 10
typedef int DataType;
typedef struct SeqList
{
DataType data[MAX];
int sz;
}SeqList, *pSeqList;
void InitSeqList(pSeqList ps);
void PushBack(pSeqList ps, DataType d);
void PopBack(pSeqList ps);
void Display(const pSeqList ps);
void PushFront(pSeqList ps, DataType d);
void PopFront(pSeqList ps);
int Find(pSeqList ps, DataType d);
void Insert(pSeqList ps, DataType d, int pos);
void Remove(pSeqList ps, DataType d);
void RemoveAll(pSeqList ps, DataType d);
void Reverse(pSeqList ps);
void Sort(pSeqList ps);
int BinarySearch(pSeqList ps, DataType d);
#endif //__SEQLIST_H__
test.c
#include "SeqList.h"
void test1()
{
SeqList my_list;
InitSeqList(&my_list);//初始化顺序表
PushBack(&my_list, 1);
PushBack(&my_list, 2);
PushBack(&my_list, 3);
PushBack(&my_list, 4);
Display(&my_list);
//打印时候可以不传地址,因为只打印,不会改它,只要拿到里面的数据就可以了。
//形参是实参的临时拷贝,数据sz全部传过去,打印没有任何问题,但这样做不好。
//结构体传参,传地址,不要传变量,因为传变量系统压栈的开销比较大,结构体可能会大。所以传地址比较好。
PopBack(&my_list);
Display(&my_list);
PopBack(&my_list);
Display(&my_list);
PopBack(&my_list);
Display(&my_list);
PopBack(&my_list);
Display(&my_list);
}
void test2()
{
SeqList my_list;
InitSeqList(&my_list);//初始化顺序表
PushFront(&my_list, 1);
PushFront(&my_list, 2);
PushFront(&my_list, 3);
PushFront(&my_list, 4);
Display(&my_list);
PopFront(&my_list);
Display(&my_list);
PopFront(&my_list);
Display(&my_list);
PopFront(&my_list);
Display(&my_list);
PopFront(&my_list);
Display(&my_list);
}
void test3()
{
SeqList my_list;
int pos = 0;
InitSeqList(&my_list);//初始化顺序表
PushFront(&my_list, 1);
PushFront(&my_list, 2);
PushFront(&my_list, 3);
PushFront(&my_list, 4);
PushFront(&my_list, 5);
pos=Find(&my_list,4);
if (pos == -1)
{
printf("要查找的元素不存在\n");
}
else
{
Insert(&my_list, 6, pos);//把6插入pos的位置上
}
Display(&my_list);
}
void test4()
{
SeqList my_list;
int pos = 0;
InitSeqList(&my_list);//初始化顺序表
PushFront(&my_list, 1);
PushFront(&my_list, 2);
PushFront(&my_list, 3);
PushFront(&my_list, 4);
PushFront(&my_list, 5);
Display(&my_list);
Remove(&my_list, 3);
Display(&my_list);
}
void test5()
{
SeqList my_list;
int pos = 0;
InitSeqList(&my_list);//初始化顺序表
PushFront(&my_list, 1);
PushFront(&my_list, 3);
PushFront(&my_list, 3);
PushFront(&my_list, 2);
PushFront(&my_list, 3);
PushFront(&my_list, 4);
PushFront(&my_list, 3);
PushFront(&my_list, 5);
PushFront(&my_list, 3);
Display(&my_list);
RemoveAll(&my_list, 3);
Display(&my_list);
}
void test6()
{
SeqList my_list;
InitSeqList(&my_list);//初始化顺序表
PushFront(&my_list, 1);
PushFront(&my_list, 2);
PushFront(&my_list, 3);
PushFront(&my_list, 4);
PushFront(&my_list, 5);
Display(&my_list);
Reverse(&my_list);
Display(&my_list);
}
void test7()
{
SeqList my_list;
int pos = 0;
InitSeqList(&my_list);//初始化顺序表
PushFront(&my_list, 1);
PushFront(&my_list, 2);
PushFront(&my_list, 3);
PushFront(&my_list, 4);
PushFront(&my_list, 5);
Display(&my_list);
Sort(&my_list);
Display(&my_list);
pos = BinarySearch(&my_list, 3);
printf("%d\n", pos);
pos = BinarySearch(&my_list, 6);
printf("%d\n", pos);
}
int main()
{
test7();
system("pause");
return 0;
}
SeqList.c
#include "SeqList.h"
void InitSeqList(pSeqList ps)
{
ps->sz = 0;
memset(ps->data, 0, sizeof(ps->data));
}
void PushBack(pSeqList ps, DataType d)//在尾部添加元素
{
assert(ps != NULL);
if (ps->sz == MAX)//当元素个数达到最大就不能继续往上添加了
{
return;
}
ps->data[ps->sz] = d;
ps->sz++;//尾部插入元素
}
void PopBack(pSeqList ps)//在尾部删除元素
{
assert(ps != NULL);
if (ps->sz == 0)//当元素个数为0时就不能继续删除了
{
return;
}
ps->sz--;
}
void Display(const pSeqList ps)
{
int i = 0;
assert(ps != NULL);
for (i = 0; i < ps->sz; i++)
{
printf("%d ", ps->data[i]);
}
printf("\n");
}
void PushFront(pSeqList ps, DataType d)//头部插入
{
assert(ps != NULL);
if (ps->sz < MAX)
{
int i = 0;
memmove(ps->data+1,ps->data,sizeof(DataType)*(ps->sz));//memmove(目标,源,字节个数)//sizeof(DataType)*(ps->sz):该类型的字节数*元素的个数=总字节数
ps->data[0] = d;
ps->sz++;
}
//把所有元素向后挪,再把元素插上去
}
void PopFront(pSeqList ps)//头部删除
{
int i = 0;
assert(ps != NULL);
if (ps->sz == 0)//当元素个数为0时就不能继续删除了
{
return;
}
for (i = 0; i < ps->sz-1; i++)//为了不越界访问
{
ps->data[i] = ps->data[i + 1];
//但还有一个元素不能删
}
ps->sz--;//可以把最后一个元素也删了
}
int Find(pSeqList ps, DataType d)//查找指定元素//int 指的是返回的下标
{
int i = 0;
assert(ps != NULL);
for (i = 0; i < ps->sz ; i++)
{
if (d == ps->data[i])
return i;
}
return -1;
}
void Insert(pSeqList ps, DataType d, int pos)//指定位置插入
{
int i = 0;
assert(ps != NULL);
if (ps->sz == MAX)
{
return;
}
for (i = ps->sz; i > pos; i--)
{
ps->data[i] = ps->data[i - 1];//把元素向后移一个位置
}
ps->data[pos] = d;
ps->sz++;
}
void Remove(pSeqList ps, DataType d)//删除指定位置元素
{
int pos = 0;
assert(ps != NULL);
pos=Find(ps,d);
if (pos != -1)
{
memmove(ps->data + pos, ps->data + pos + 1, (ps->sz - pos - 1)*sizeof(DataType));
ps->sz--;
}
}
void RemoveAll(pSeqList ps, DataType d)//删除指定所有元素,一个元素可能出现多次,把这个元素都删掉。
{
int pos = 0;
while ((pos = Find(ps,d))!=-1)
{
Remove(ps, d);
}
}
void Reverse(pSeqList ps)//把顺序表的元素逆序
{
DataType*left = ps->data;
DataType*right = ps->data+ps->sz-1;
assert(ps != NULL);
while (left < right)//逆序
{
DataType tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
void Sort(pSeqList ps)//重新排序
{
int i = 0;
int j = 0;
assert(ps != NULL);
for (i = 0; i < ps->sz - 1; i++)
{
for (j = 0; j < ps->sz - 1 - i; j++)
{
DataType tmp = ps->data[j];
ps->data[j] = ps->data[j + 1];
ps->data[j + 1] = tmp;
}
}
}
int BinarySearch(pSeqList ps, DataType d)//二分查找
{
int left = 0;
int right = ps->sz - 1;
assert(ps != NULL);
while (left<=right)
{
int mid = left + ((right - left) >> 1);
if (d == ps->data[mid])
{
return mid;
}
else if (d < ps->data[mid])
{
right = mid - 1;
}
else
{
left = mid + 1;
}
}
}