线性表分为:顺序存储结构和连存储结构
顺序存储结构的优点:
1.空间利用率高,几乎不需要额外的空间开销.
2.数据的逻辑结构和物理结构完全一致.
3.结点地址计算的时间和线性表的规模大小无关.
4.可以用一维数组实现存储.
但是有两个缺点:
1.顺序存储结构的存储空间是静态分配,必须有足够大的连续存储空间,如果不能则无法实现存储.在建立顺序表时,存储空间大小有时无法确切估计,估计过大回会使空闲区段的部分空间长期闲置,估计过小则会在操作中因空间不够而产生溢出.
2.插入操作和产出操作在大多数情况下,引起大量节点的频繁移动,降低了算法的时间效率.
因此:顺序存储结构 比较适合规模较小,长度变化不大且不很频繁的线性表存储实现.
克服线性表顺序存储结构的方法采用链表存储结构,链表存储结构的存储分配方式灵活,有效性好.用链表存储结构存储的线性表称为"链表".
代码实现--------顺序表
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define OK 0
#define OVERFLOW 1
#define ERROR -1
#define TURE 1
#define FALSE 0
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
typedef int ElemType;
typedef int Status;
typedef struct
{
ElemType *elem; //存储空间基址
int length; //当前长度
int listsize; //当前分配的存储容量(以sizeof(ElemType)为单位)
}SqList;
Status InitList_Sq(SqList &L)
//构造一个空的线性表L
{
L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(!L.elem) return OVERFLOW;
L.length=0;
L.listsize=LIST_INIT_SIZE;
return OK;
}
Status ListInsert_Sq(SqList &L,int i,ElemType e)
//在顺序线性表L中第i个位置之前插入新的元素e
//i的合法值为1<=i<=ListLength.Sq(L)+1
{
ElemType* newbase, * q, * p;
if(i<1||i>L.length+1) return ERROR;
if(L.length>=L.listsize)
{
newbase=(ElemType*)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
if(!newbase) exit (OVERFLOW);
L.elem=newbase;
L.listsize+=LISTINCREMENT;
}
q=&(L.elem[i-1]);
for(p=&(L.elem[L.length-1]);p>=q;--p)
*(p+1)=*p;
*q=e;
++L.length;
return OK;
}
Status ListDelete_Sq(SqList &L,int i,ElemType e)
//在顺序线性表中删除第i个元素,并用e返回其值
{
ElemType * q, * p;
if((i<1)||(i>L.length)) return ERROR;
p=&(L.elem[i-1]);
e=*p;
q=L.elem+L.length-1;
for(++p;p<=q;++p)
*(p-1)=*p;
--L.length;
return OK;
}
Status Input(SqList &L,int n)
//输入函数
{
int i,m;
printf("请输入各元素的值:\n");
while(n--)
{
scanf("%d",&m);
ListInsert_Sq(L,L.length+1,m);
}
}
Status Output(SqList &L)
//输出函数
{
int i;
for(i=0;i<L.length;i++)
printf("%d\t",L.elem[i]);
printf("\n");
}
int main()
{
int i,n;
SqList L;
ElemType e;
InitList_Sq(L);
printf("请输入顺序表长度:\n");
scanf("%d",&i);
//L.length=i;
Input(L,i);
while(1)
{
system("cls");
Output(L);
printf("1.插入元素 2.删除元素\n");
scanf("%d",&n);
if(!n) break;
else if(n==1)
{
system("cls");
while(1)
{
Output(L);
printf("请输入要插入的位置或输入0返回上一级\n");
scanf("%d",&n);
if(!n) break;
system("cls");
Output(L);
printf("请输入要插入的元素值:\n");
scanf("%d",&i);
//ListInsert_Sq(L,n,i);
system("cls");
if(!ListInsert_Sq(L,n,i))
{
printf("操作成功\n");
}
else
{
printf("操作失败\n");
}
}
}
else if(n==2)
{
system("cls");
while(1)
{
Output(L);
printf("请输入要删除的位置或输入0返回上一级\n");
scanf("%d",&n);
//ListDelete_Sq(L,n,e);
if(!n) break;
system("cls");
if(!ListDelete_Sq(L,n,e))
{
printf("删除成功\n");
}
else
printf("删除失败\n");
}
}
}
return 0;
}
代码实现--------单链表
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include <iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define TURE 1
#define FALSE 0
#define OVERFLOW -1
typedef int Status;
typedef int ElemType;
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode,*Linklist;
//创建单链表
void CreateList_L(Linklist &L,int n){
//逆序输入n个元素的值,建立带表头节点的单链表L
L=(Linklist)malloc(sizeof(LNode));
L->next=NULL; // 先建立一个带头结点的单链表
int i;
Linklist p;
cout<<"请输入元素值:"<<endl;
for(i=n;i>0;--i){
p=(Linklist)malloc(sizeof(LNode));//生成新节点
cin>>p->data;
p->next=L->next;L->next=p; //插入到表头
}
}
//获取第i个元素的值
Status GetElem_L(Linklist L,int i,ElemType &e) {
//L为带头节点的单链表头指针
//当第i个元素存在时,其值赋给e,返回OK,否则返回ERROR
Linklist p;
p = L->next;
int j = 1;
//初始化 p指向第一个结点,j计数
while (p&&j < i) {//顺时针查找
p = p->next;
++j;
}
if (!p || j > i) {
return ERROR;
}
e = p->data;
return OK;
}
Status ListInsert_L(Linklist &L, int i, ElemType e) {
//在带头节点在单链线性表L中第i个位置之前插入元素e
Linklist p;
p = L;
int j = 0;
while (p&&j<i-1) {
p = p->next;
++j; //找到第i-1个节点
}
if (!p || j > i - 1) return ERROR;
Linklist s;
s = (Linklist) malloc(sizeof(LNode)); //生成新节点s
s->data = e;
s->next = p->next;
p->next = s;
return OK;
}
Status ListDelete_L(Linklist &L, int i, ElemType &e) {
//删除第i个元素,返回其值 p->next = p->next->next
Linklist p;
p = L;
int j = 0;
while (p->next && j < i - 1) {
p = p->next;
++j;
}
if (!(p->next) || j > i - 1) return ERROR;
Linklist q;
q = p->next;
p->next = q->next;
e = q->data;
free(q);
return OK;
}
void showL(Linklist L){
Linklist p;
p=L->next;
while(p!=NULL){
printf("%d ",p->data);
p=p->next;
}
}
int main() {
Linklist L;
CreateList_L(L,5) ;//创建长度5的单链表
cout<<"此时的单链表:\n";
showL(L);
cout<<"\n";
int n;
cout<<"请输入要插入的元素:"<<endl;
cin>>n;
ListInsert_L(L,1,n);
cout<<"插入后的链表:"<<endl;
showL(L);
cout<<"\n";
int i,e;
cout<<"请输入要删除的第几个元素:"<<endl;
cin>>i;
ListDelete_L(L,i,e);
cout<<"删除后的链表:"<<endl;
showL(L);
}