数据结构(二)—–顺序表
顺序存储:用一组地址连续的存储单元依次存放线性表中的数据元素的存储结构。用顺序存储的线性表称为顺序表,所有数据元素的存储位置均取决于第一个元素的存储位置。
特点:1.逻辑上相邻的数据元素,赋以相邻的存储位置 2.存储密度高 3.便于随机存储 4.不便于插入、删除操作
/*
作者:mys
功能:顺序表的操作:创建、初始化、显示、插入、删除、取元素
日期:2018/7/25
*/
#include<stdio.h>
#include<malloc.h>
//结构体
struct seqList
{
int data[100];
int length;
};
//初始化顺序表
struct seqList * initSeqList(struct seqList *L,int a[],int n);
//判断是否为空表
int isEmptyList(struct seqList *L);
//求顺序表的长度
int lengthList(struct seqList *L);
//输出顺序表
void dispSeqList(struct seqList *L);
//插入元素 index插入位置 element插入元素
struct seqList * insertSeqList(struct seqList *L, int index, int element);
//删除元素 index删除位置 element删除元素
struct seqList * deleteSeqList(struct seqList *L, int index);
//按元素位置获取元素值 index位置
int getElement(struct seqList *L, int index);
//按元素值查找元素位置 element元素值
int locateElement(struct seqList *L, int element);
//实例:实现对顺序表循环右移k位的操作
void shiftRight(struct seqList *L, int a[], int k, int len);
void main()
{
int i;
struct seqList *L;
L = (struct seqList *)malloc(sizeof(struct seqList));//分配内存空间
int a[10] = { 2, 4, 6, 8, 3, 5,9, 20, 30, 10 };
initSeqList(L,a,10);
printf("原序列:");
dispSeqList(L);
insertSeqList(L, 0, 12);
insertSeqList(L, 0, 7);
printf("插入后序列:");
dispSeqList(L);
deleteSeqList(L, 3);
printf("删除后序列:");
dispSeqList(L);
printf("位置为2的元素值:%d\n", getElement(L, 2));
printf("元素值为5的元素位置:%d\n", locateElement(L, 5));
shiftRight(L, a, 4, L->length);
printf("右移4位后序列:");
dispSeqList(L);
}
struct seqList * initSeqList(struct seqList *L,int a[],int n)
{
int i;
for (i = 0; i < n; i++)
{
L->data[i] = a[i];
}
L->length = n;
return L;
}
int isEmptyList(struct seqList *L)
{
return(L->length == 0);
}
int lengthList(struct seqList *L)
{
return L->length;
}
void dispSeqList(struct seqList *L)
{
int i;
if (!isEmptyList(L))
{
for (i = 0; i < L->length; i++)
printf("%4d", L->data[i]);
}
printf("\n");
}
struct seqList * insertSeqList(struct seqList *L, int index, int element)
{
int i;
//插在最后面
if (index>=L->length)
{
L->data[L->length] = element;//插入
}
else
{
//插在中间或前面
for (i = L->length; i > index; i--)
L->data[i] = L->data[i - 1];//依次后移一位
L->data[index] = element;//插入
}
L->length++;//长度+1
return L;
}
struct seqList * deleteSeqList(struct seqList *L, int index)
{
int i;
//判断删除位置是否在顺序表内
if (index < 0 || index >= L->length)
printf("删除出错!");
else
{
for (i = index + 1; i < L->length; i++)
L->data[i - 1] = L->data[i];//依次前移一位
L->length--;
}
return L;
}
int getElement(struct seqList *L, int index)
{
//判断所取位置是否在顺序表内
if (index < 0 || index >= L->length)
{
printf("无法取出!");
return 0;
}
else
return L->data[index];
}
int locateElement(struct seqList *L, int element)
{
int i=0;
while (i < L->length&&L->data[i] != element)
i++;
if (i >= L->length)
return 0;
else
return i;
}
void shiftRight(struct seqList *L,int a[], int k, int len)
{
int i, j, temp, p, l;
for (i = 1; i <= k; i++)
if (len%i == 0 && k%i == 0)
p = i;//求len、k的最大公因数
for (i = 0; i < p; i++)
{
j = i;
l = (i + len - k) % len;
temp = L->data[i];
while (l != i)
{
L->data[j] = L->data[l];
j = l;
l = (j + len - k )%len;
}//循环右移一位
L->data[j] = temp;
}
}
实例应用:
编写一个顺序表类的成员函数,实现对顺序表循环右移k位的操作。 即原来顺序表为(a1, a2, …, an - k, an - k + 1, …, an),循环向右移动k位后变成(an - k + 1, …, an, a1, a2, …, an - k)要求时间复杂度为O(n)
void shiftRight(struct seqList *L,int a[], int k, int len)
{
int i, j, temp, p, l;
for (i = 1; i <= k; i++)
if (len%i == 0 && k%i == 0)
p = i;//求len、k的最大公因数
for (i = 0; i < p; i++)
{
j = i;
l = (i + len - k) % len;
temp = L->data[i];
while (l != i)
{
L->data[j] = L->data[l];
j = l;
l = (j + len - k )%len;
}//循环右移一位
L->data[j] = temp;
}
}