您的位置:首页 > 理论基础 > 数据结构算法

数据结构:线性表之顺序表

2017-05-30 12:35 246 查看

数据结构:线性表之顺序表

需求:实现线性表的数组方式实现,

功能:实现数组表的增删改查

实现:

将各个功能单独封装到函数

初始化:由于数据都不是在主函数中创建,出函数后无法使用。所以元素和元素集合(person and men)使用动态内存创建。

增:将person结构体封装到men结构体中,以指针数组方式存储,每次添加一个元素并记录表长,

删:删除元素,并移动元素填补空位。更新表长。释放内存。时间复杂度 O(n)

改:由于是指针数组,更改指针指向,释放内存即可,(未实现)

查:遍历表元素,对比元素内容(compareP())返回下标。时间 复杂度 O(n)

插入:移动元素得到空位,再插入元素。时间复杂度 O(n)

总结:

线性表的数组实现是最简单的顺序存储结构,其元素顺序存储在内存中。即逻辑结构和存储结构相同
由于这次实现用的是指针数组,所以元素是分散存储的。不知还算不算顺序表。

算法分析:
数组结构的删除和插入都需要移动元素,在最坏情况下要移动整个表,最好情况下无需移动。所以时间复杂的为 O(n)
效率并不高。查找算法需要遍历数组,所以复杂度也是O(n)。
数组结构的优势在于其数据是连续存储在内存中,通过指针运算可以快速访问数组任意 指定 位置的元素。
适合按下标访问,删除和插入元素较少的场景

最后感慨两句:Java的垃圾回收机制实现的内存管理确实大大方便了程序开发。


头文件代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef PERSON_H_INCLUDED
#define PERSON_H_INCLUDED

#define max 10

typedef struct {
char name[10];
short age;
}person;

typedef struct {
person *p[max];
int length;
}men;

#endif // PERSON_H_INCLUDED


demo 代码如下:

#include "person.h"
//初始化 person, 返回person指针
person *newP(char *name,int age){
//检查参数
if(name == NULL)return NULL;
//动态分配内存
person *p = (person *)malloc(sizeof(person));
p->age = age;
strcpy(p->name,name);
return p;
}

//初始化线性表, 返回表men结构指针
men *newM(){
men *m = (men *)malloc(sizeof(men));
m->length = 0;//length代表可存储元素的位置的下标
return m;
}

//添加元素 返回逻辑值(是否成功添加元素)
int add(men *m, person *p){
//检查参数
if(m == NULL || p == NULL)exit(1);

if(m->length < max){
m->p[m->length++] = p;
return 1;
}
printf("person size don't enough , need more size !!!");
return 0;
}

//插入元素 返回逻辑值(是否成功插入元素)
int insert(men *m,person *p,int index){
//检查参数
if(m == NULL || p == NULL)exit(1);

if(index >= 0 && index < m->length){
int i;
//move 元素
//从下标length开始,交换p[length]和p[length-1];直到下标递减到index时,便腾出了一个空位(index)
for(i = m->length+
a223
+; i > index; i--){
m->p[i] = m->p[i-1];
}

//insert  元素
m->p[i] = p;
return 1;
}
printf("index error !!!");
return 0;
}

//删除元素 返回逻辑值(是否成功delete元素)
int myremove(men *m,int index){
//检查参数
if(m == NULL)exit(1);

if(index >= 0 && index < m->length){
int i,j;
//释放内存
free(m->p[index]);

//remove 元素
//从下标index开始交换P[index]和P[index+1]。直到length-1.
for(i = --(m->length),j = index; j < i; j++){
m->p[j] = m->p[j+1];//注意!!p[++j]不可用,取到的值还是j
//printf("test%d,%d\n",++index,index++);//?打印结果5,3 7,5
}
return 1;
}
printf("index error !!!");
return 0;
}

//查找元素 返回下标(如果找到元素)或-1(没找到)
int locateP(men *m,person *p){
int i, j;
//遍历数组比较元素,找到返回下标
for(i = 0, j = m->length; i < j; i++){
if(compareP(m->p[i],p)){
return i;
}
}
return -1;
}

//person元素比较器 返回逻辑值(元素是否相同)
int compareP(person *p1,person *p2){
if(p1 == p2){
return 1;
}

return (p1->age == p2->age && !strcmp(p1->name,p2->name));
}

void println(men *m){
int i, length = m->length;
for (i = 0; i < length; i++){
printf("%d ,name = %s,age = %d\n", i, m->p[i]->name, m->p[i]->age);

}
printf("**************************************\n");
}

int main()
{
person p1 = {"df",14};

//初始化
int *p,i;
men *m = newM();
add(m,newP("",NULL));//测试传null
add(m,newP("ww",13));
add(m,newP("ww",13));
add(m,newP("df",14));
add(m,newP("zs",15));

//求表长
printf("length = %d\n",m->length);
//遍历元素
println(m);
//插入元素
insert(m,newP("new",3),2);
println(m);
//删除元素
myremove(m,3);
println(m);
//查找元素
printf("index = %d\n",locateP(m,&p1));

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: