是一种逻辑结构, 不特指某一具体在内存中以某种物理结构存储的线性结构
线性表是指具有相同特性数据元素的有限序列
[顺序表]
[链表]
物理结构(在内存中存储方式):
连续存储, 且静态分配
数据域
结构定义:
/* *ElemType是宏定义或者typedef指定的类型名 *这里typedef是将这个结构体类型命名为SqList */
#define MAX_SIZE 100
typedef int ElemType; /**同 #define ElemType int */
typedef struct{
ElemType data[MAX_SIZE]; //data数组
int length; //顺序表长度
}SqList;//Sequence List
/**可以使用typedef或#define修改SqList的存储数据类型, 代码重用性强**/
关于#define
和 typedef
#define
只是简单的文本替换 , 除了简写基本类型名(或者已经定义类型名)外还可以用来定义常量
typedef
是对一个类型名起一个别名(原类型名依然可用), 可以对结构体这种复杂类型重命名
顺序表的存储范围[0, MAX_SIZE - 1] (参照数组的范围), MAX_SIZE即为最大的长度
常用操作
插入: 在指定位置插入指定的数据元素
指定位置要满足当前length
确定的范围
eg : 若当前顺序表长度为5, 则顺序表中有效数据的存储下标范围为[0, 4](本例从0开始)
则插入元素的位置范围为[0, 5](数组中仅有5个有效元素, 插入位置不能>=7(下标为6))
/*
*插入操作
*@param: l : 顺序表
*@param: pos : 指定插入位置
*@param: x : 指定插入数据
*@return : int(1 : 插入成功, 0 : 插入失败)
*/
int Insert(SqList &l, int pos, ElemType x){
if(l.length == MAX_SIZE) return 0;//数组已满,插入失败
if(pos < 0 || pos > l.length) return 0;//指定插入位置超出范围
for(int i = l.length - 1; i >= pos; --i)
l.data[i + 1] = l.data[i];
l.data[pos] = x;
++(l.length);
return 1;
}
删除: 删除指定位置的元素(可返回该元素值)
指定位置要满足条件(不能删除不存在位置的元素)
范围为[0, length - 1]
/*
*删除操作
*@param: l : 顺序表
*@param: pos : 指定删除位置
*@param: x : 获取删除的元素值(删除成功时)
*@return : int(1 : 删除成功, 0 : 删除失败)
*/
int Delete(SqList &l, int pos, ElemType &x){
if(pos < 0 || pos >= l.length) return 0;//指定删除位置超出范围
x = l.data[pos];
for(int i = pos; i < l.length - 1; ++i)
l.data[i] = l.data[i + 1];
--(l.length);
return 1;
}
查询: 获取指定位置的元素
由于顺序表中存放元素的事数组, 可以依据存储位置(数组下标)随机访问
查询时间复杂度O(1)
ps : 自然指定位置要满足length的范围
/*
*查询操作
*@param: l : 顺序表
*@param: pos : 指定查询位置
*@param: x : 获取查询的元素值(查询成功时)
*@return : int(1 : 查询成功, 0 : 查询失败)
*/
int GetElem(SqList l, int pos, ElemType &x){
if(pos < 0 || pos >= l.length) return 0;//超范围
x = l.data[pos];
return 1;
}
打印: 遍历输出顺序表的元素
void Print(SqList l){
int len = l.length;
if(len == 0) return;//线性表为空
for(int i = 0; i < len; ++i)
printf("%d%c", l.data[i], i == len - 1 ? '\n' : ' ');
}
获取长度
int ListLength(SqList l){
return l.length;
}
初始化:顺序表数组长度赋0值
此时顺序表数组中或许有数据存在, 但不是有效数据
,有效数据在[0, length)范围内
void InitList(SqList &l){
l.length = 0;
}
按值查询:查询指定元素在顺序表数组中的位置,若不含该元素返回-1
int LocateElem(SqList l, ElemType x){
for(int i = 0; i < l.length; ++i)
if(l.data[i] == x) return ;
return -1;
}
特点:
O(n)
,要移动元素顺序表有序化:
线性表本身是无序的(有序是指元素之间按照某种既定规则排列), 可以通过一定的插入规则使其有序
eg : 顺序表递增插入
int GetInsertPos(SqList l, ElemType x){
for(int i = 0; i < l.length; ++i)
if(l.data[i] > x) return i;
return l.length;
}
int IncreseInsert(SqList &l, ElemType x){
int pos = GetInsertPos(l, x);
return Insert(l, pos, x);
}
代码整合(CodeUp1323)
#include
/**
*CodeUp 1323
*Sequence List
**/
#define MAX_SIZE 210
#define ElemType int
#define Status int
#define OK 1
#define ERROR 0
//宏定义
typedef struct{
ElemType data[MAX_SIZE];
int length;
}SqList;
int LocateElem(SqList l, ElemType x){
for(int i = 0; i < l.length; ++i)
if(l.data[i] == x) return i;
return -1;
}
int ListLength(SqList l){
return l.length;
}
void InitList(SqList &l){
l.length = 0;
}
Status GetElem(SqList l, int pos, ElemType &e){
if(pos < 0 || pos >= l.length) return ERROR;
e = l.data[pos];
return OK;
}
Status Insert(SqList &l, int pos, ElemType x){
int len = ListLength(l);
if(pos < 0 || pos > len || len == MAX_SIZE)
return ERROR;
for(int i = len - 1; i >= pos; --i)
l.data[i + 1] = l.data[i];
l.data[pos] = x;
++(l.length);
return OK;
}
Status Delete(SqList &l, int pos, ElemType &e){
if(pos < 0 || pos >= l.length) return ERROR;
e = l.data[pos];
for(int i = pos; i < l.length - 1; ++i)
l.data[i] = l.data[i + 1];
--(l.length);
return OK;
}
void Print(SqList l){
int len = ListLength(l);
for(int i = 0; i < len; ++i)
printf("%d%c", l.data[i], i == len - 1 ? '\n' : ' ');
}
void Union(SqList &la, SqList lb){
int len_la = ListLength(la);
int len_lb = ListLength(lb);
for(int i = 0; i < len_lb; ++i){
if(LocateElem(la, lb.data[i]) == -1)
Insert(la, len_la++, lb.data[i]);
Print(la);
}
}
SqList la, lb;
int main(){
int m, n;
int v;
while(scanf("%d", &m) != EOF){
InitList(la);
InitList(lb);
for(int i = 0; i < m; ++i){
scanf("%d", &v);
Insert(la, i, v);
}
scanf("%d", &n);
for(int i = 0; i < n; ++i){
scanf("%d", &v);
Insert(lb, i, v);
}
Print(la);
Print(lb);
Union(la, lb);
printf("\n");
}
return 0;
}
物理结构
形式:
单链表
结构定义
typedef struct Node{
ElemType data;
Node * next;
}LNode;
//头结点不存储信息
新建结点
LNode * NewNode(ElemType x){
LNode * res = (LNode *)malloc(sizeof(LNode));
res->data = x;
res->next = NULL;
return res;
}
插入操作:
void InsertHead(LNode * head, LNode *tmp){
tmp->next = head->next;
head->next = tmp;
}
void InsertTail(LNode * head, LNode * tmp){
LNode * cur = head;
while(cur->next) cur = cur->next;
cur->next = tmp;
}
两递增有序单链表的归并
void Merge1(LNode * A, LNode * B, LNode * &C){
C = A;
LNode * p = A->next;
LNode * q = B->next;
free(B);
LNode * r = C;
while(p != NULL && q != NULL){
if(p->data <= q->data){
r->next = p;
r = r->next;
p = p->next;
}else{
r->next = q;
r = r->next;
q = q->next;
}
}
if(p != NULL) r->next = p;
if(q != NULL) r->next = q;
}
两递增有序单链表归并成递减
void Merge2(LNode * A, LNode * B, LNode * &C){
C = A;
LNode * p = A->next;
LNode * q = B->next;
free(B);
LNode * r;
while(p != NULL && q != NULL){
if(p->data <= q->data){
r = p;
p = p->next;
}else{
r = q;
q = q->next;
}
InsertHead(C, r);
}
while(p != NULL) {
r = p;
p = p->next;
InsertHead(C, r);
}
while(q != NULL) {
r = q;
q = q->next;
InsertHead(C, r);
}
}
整合(CodeUp1324):
#include <stdio.h>
#include <stdlib.h>
#define ElemType int
typedef struct Node{
ElemType data;
Node * next;
}LNode;
LNode * NewNode(ElemType x){
LNode * res = (LNode *)malloc(sizeof(LNode));
res->data = x;
res->next = NULL;
return res;
}
void InsertHead(LNode * head, LNode *tmp){
tmp->next = head->next;
head->next = tmp;
}
void InsertTail(LNode * head, LNode * tmp){
LNode * cur = head;
while(cur->next) cur = cur->next;
cur->next = tmp;
}
void Merge1(LNode * A, LNode * B, LNode * &C){
C = A;
LNode * p = A->next;
LNode * q = B->next;
free(B);
LNode * r = C;
while(p != NULL && q != NULL){
if(p->data <= q->data){
r->next = p;
r = r->next;
p = p->next;
}else{
r->next = q;
r = r->next;
q = q->next;
}
}
if(p != NULL) r->next = p;
if(q != NULL) r->next = q;
}
void Merge2(LNode * A, LNode * B, LNode * &C){
C = A;
LNode * p = A->next;
LNode * q = B->next;
free(B);
LNode * r;
while(p != NULL && q != NULL){
if(p->data <= q->data){
r = p;
p = p->next;
}else{
r = q;
q = q->next;
}
InsertHead(C, r);
}
while(p != NULL) {
r = p;
p = p->next;
InsertHead(C, r);
}
while(q != NULL) {
r = q;
q = q->next;
InsertHead(C, r);
}
}
void Print(LNode * head){
LNode * cur = head->next;
printf("%d", cur->data);
cur = cur->next;
while(cur != NULL){
printf(" %d", cur->data);
cur = cur->next;
}
printf("\n");
}
int main(){
int m, n;
int v;
while(scanf("%d", &m) != EOF){
LNode * A = NewNode(-1);
LNode * B = NewNode(-1);
LNode * C;
for(int i = 0; i < m; ++i){
scanf("%d", &v);
InsertTail(A, NewNode(v));
}
scanf("%d", &n);
for(int i = 0; i < n; ++i){
scanf("%d", &v);
InsertTail(B, NewNode(v));
}
Merge1(A, B, C);
Print(C);
}
return 0;
}
特点