线性表定义
- 线性表是零个或多个数据元素构成的线性序列,是最基础、最常用的一种线性数据结构。
线性表的顺序存储结构和实现
线性表的顺式存储.c
#include<stdio.h> #include<stdlib.h> #define ERROR 0 #define OK 1 #define Overflow 2//上溢 #define Underflow 3//下溢 #define NotPresent 4//元素不存在 #define Duplicate 5//有重复元素 typedef int EleType; typedef struct//线性表的顺序表示 { int n;//顺序表中数据元素的个数 int maxLength;//顺序表最大允许长度 ElemType *element;//自定义类型 }SeqList; typedef int Status; //为了方便以后如果进行数据类型替换所进行的预先处理,是一种很成熟的做法。 Status Init(SeqList *L,int mSize)//initialize { L->maxLength=mSize; L->n=0; L->element=malloc(sizeof(ElemType)*msize);//动态生成一维空间 if(!L->element) return ERROR; return OK; } Status Find(SeqList L,int i,ElemType *x)//查找 { if(i<0||i>L.n-1) //此处体现了算法的健壮性 return ERROR;//判断i是否越界 *x=L.element[i];//取出elment[i]的值 return OK; } Status Insert(SeqList *L,int i,ElemType x) { int j; if(i<-1||i>L->n-1)//判断下标是否越界 return ERROR; if(L->n==L->maxLength)//判断顺序表是否已经满了 return ERROR; for(j=L->n-1;j>1;j--) L->element[j+1]=L->element[j];//从后往前移动元素 L->element[i+1]=x;//将新元素放入下标为i+1的位置 L->n=L->n+1; return OK; } /*
插入操作的平均次数为E=∑(n-i-1)/(n+1)=n/2,算法复杂度为O(n)
*/
Status Delete(SeqList *L,int i) { int j; if(i<0||i>L->n-1)//判断下标是否越界 retyrn ERROR; if(!L->n)//判断顺序表是否为空 return ERROR; for(j=i+1;j<L->n;j++) L->element[j+1]=L->element[j];//从前往后逐个前移 L->n=L->n-1; //顺序表元素的个数减1 return OK; }
/*
删除操作的平均次数为E=∑(n-i-1)/(n)=(n-1)/2,算法复杂度为O(n)
*/
Status Output(SeqList L)//输出
{
int j;
if(!L.n)//判断顺序表是否为空
return ERROR;
for(j=0;j<=L.n-1;j++)
printf("%d ",L.element[i]);
return OK;
}
Status Destroy(SeqList *L)//撤销
{ (*L).n=0;
(*L).maxLength=0;
free((*L).element);
}
void main(){
int i;
SeqList list;
Init(&list,10);
for(i=0;i<9;i++)
Insert(&list,i-1,i);
Output(list);
Delete(&list,0);
Output(list);
Destroy(&list);
}
线性表的链式存储结构和实现
采用链式存储结构的线性表称为链表。链表有单链表、循环链表、双向链表、循环双向链表等多种类型。
线性表的链式存储.c
#include<stdio.h> #include<stdlib.h> #define ERROR 0 #define OK 1 #define Overflow 2//上溢 #define Underflow 3//下溢 #define NotPresent 4//元素不存在 #define Duplicate 5//有重复元素 typedef int ElemType; typedef int Status; typedef struct Node { ElemType element;//结点的数据域 struct Node *link;//结点的指针域 }Node; typedef struct { int n;//数据元素的个数 struct Node *first;//头指针 }SingleList; Status Init(SingleList *L)//initialize { L->first=NULL; L->n=0; return OK; } Status Find(SingleList L,int i,ElemType *x)//查找 { Node *p; int j; if(i<0||i>L.n-1) return ERROR;//判断i是否越界 p=L.first; for(j=0;j<i;j++)p=p->link;//从头结点开始查找a *x=p->element;//取出ai的值 return OK; } Status Insert(SingleList *L,int i,ElemType x) { Node *p,*q; int j; if(i<-1||i>L->n-1)//判断下标是否越界 return ERROR; p=L->first; for(j=0;j<i;j++)p=p->link; q=malloc(sizeof(Node));//生成新结点 q->element=x; if(i>-1) { q->link=p->link;//新结点插在p结点之后 p->link=q; } else { q->link=L->first;//插在头结点之前,成为新头结点 L->first=q; } L->n=L->n+1; return OK; } Status Delete(SingleList *L,int i) { Node *p,*q; int j; if(!L->n)return ERROR; if(i<-1||i>L->n-1)//判断下标是否越界 return ERROR; p=L->first; q=L->first; for(j=0;j<i;j++)q=q->link; if(i==0) L->first=L->first->link;//Delete head else{ p=q->link; q->link=p->link; } free(p); L->n=L->n-1; return OK; } Status Output(SingleList L)//输出 { Node *p; if(!L.n)//判断顺序表是否为空 return ERROR; p=L.first; while(p) { printf("%d ",p->element); p=p->link; } printf(" "); return OK; } Status Destroy(SingleList *L)//撤销 { Node *p; while (L->first) { p=L->first->link;//保存后继地址防止断链 free(L->first);//释放 L->first=p; } return OK; } void main(){ int i; int x; SingleList list; Init(&list); for(i=0;i<9;i++) Insert(&list,i-1,i); Output(list); // Delete(&list,0); //Output(list); Find(list,6,&x); printf("%d ",x); Destroy(&list); }
单链表的逆置.c
#include <stdio.h> #include <stdlib.h> typedef int ElemType; typedef int Status; typedef struct Node { ElemType element;//结点的数据域 struct Node *link;//结点的指针域 }Node; typedef struct { int n;//数据元素的个数 struct Node *first;//头指针 }SingleList; Node *CreatList(void) { int val, i, n; Node *head, *p, *q; head = NULL; printf("请输入元素个数: "); scanf("%d", &n); printf("请输入%d个元素: ",n); for(i=0; i<n; ++i) { scanf("%d", &val); p = (Node *)malloc(sizeof(Node)); p->element = val; if(head==NULL) q=head =p; else q->link = p; q = p; } p->link = NULL; return head; } //链表的逆置 Node *ReverseList(Node *head) { Node *p,*q,*r; p=head; q=r=NULL; while(p) { q = p->link; p->link = r; r = p; p = q; } return r; } //输出链表 void Output(Node *head) { Node *p; p=head; while(p) { printf("%d ",p->element); p=p->link; } printf(" "); } int main(void) { Node *head; head = CreatList(); printf("链表逆置前的数据: "); Output(head); head = ReverseList(head); printf("链表逆置后的数据: "); Output(head); return 0; }