定义
具有相同数据类型的n个数据元素的有限序列一种逻辑结构(表示数据之间的一一对应关系)
数据元素:数据元素是数据的基本单位;有数据项构成。
基本操作
lnitList(&L):初始化表。构建一个空的线性表
DestroyList(&L):销毁操作,销毁线性表,释放线性表L所占的内存空间。
ListInsert(&L,i,e): 插入操作。在表L的第i个位置上插入指定元素e。
ListDelete(&L,i,&e):删除操作。删除表L中第i个位置的元素,并用e返回删除元素的值。
LocateElem(L,e):按值查找操作。
GetElem(L,i):按位查找操作。
Length(L):求表长。
Print List(L):输出操作。
Empty(L):判空操作。
存储
顺序表
定义:用顺序存储的方式实现线性表
静态分配
#include <stdio.h> #define MaxSize 10 typedef struct{ int data[MaxSize]; int length; }SqList; void InitList(SqList &L){ for(int i=0;i<MaxSize;i++){ L.data[i]=0; } L.length=0; } int main() { SqList L; InitList(L); return 0; }
动态分配
C:malloc动态申请内存空间;free动态释放内存空间
C++:new动态申请内存空间;delete动态释放内存空间
#include <stdlib.h> #include <stdio.h> #define InitSize 10 typedef struct{ int *data; int MaxSize; int length; }SeqList; void InitList(SeqList &L){ L.data=(int *)malloc(InitSize*sizeof(int)); L.length=0; L.MaxSize=InitSize; } void IncreaseSize(SeqList &L,int len){ int *p=L.data; L.data=(int *)malloc((L.MaxSize+len)*sizeof(int)); for(int i=0; i<L.length;i++){ L.data[i]=p[i]; } L.MaxSize=L.MaxSize+len; free(p); } int main() { SeqList L; InitList(L); IncreaseSize(L,7); return 0; }
特点
-
随机访问,可以在O(1)时间内找到第i个元素
-
存储密度高,每个节点只存储数据元素
-
拓展容量不方便(即便采用动态分配的方式实现,拓展长度的时间复杂度也比较高)
-
插入,删除操作不方便,需要移动大量元素。
基本操作
-
插入 删除 按位查找
#include <stdlib.h> #include <stdio.h> #define MaxSize 10 typedef struct{ int data[MaxSize]; int length; }SqList; void InitList(SqList &L){ for(int i=0;i<MaxSize;i++){ L.data[i]=0; } L.length=0; } bool ListInsert(SqList &L,int i, int e){ for(int j=L.length;j>=i;j--){ L.data[j]= L.data[j-1]; } L.data[i-1] = e; L.length++; return true; } bool ListDelete(SqList &L,int i, int &e){ e=L.data[i-1]; for(int j=i;j<L.length;j++){ L.data[j-1]= L.data[j]; } L.length--; return true; } int GetElem(SqList L ,int i){ return L.data[i-1]; } int LocateElem(SqList L,int e){ for(int i = 0;i<MaxSize;i++){ if(L.data[i]==e){ return i+1; } } return 0; } int main() { SqList L; InitList(L); ListInsert(L,3,3); int e= -1; ListDelete(L,3,e); int a = GetElem(L,3); return 0; }
单链表
定义
struct LNode{ ElemType data; struct LNode *next; }; //增加节点 struct LNode *p = (struct LNode*)malloc(sizeof(struct LNode));
typedef<数据类型><别名>
不带头结点单链表
typedef struct LNode{ ElemType data; struct LNode *next; }LNode,*LinkList; bool Initlist(LinkList &L){ L= NULL; return true; } void test(){ LinkList L;(没有创建结点) Initlist(L); }
带头结点单链表(写代码方便)
typedef struct LNode{ ElemType data; struct LNode *next; }LNode,*LinkList; bool Initlist(LinkList &L){ L= (LNode *)malloc(sizeof(LNode)); if(L==NUll){ return false; } L->next =NULL; return true; } void test(){ LinkList L;(没有创建结点) Initlist(L); }
基本操作
ListInsert(&L,i,e):插入操作。按位序删除
//带头结点 bool ListInsert(LinkList &L,int i,Elemtype e){ if(i<1) return false; LNode *p; int j=0; p = L;//指向头结点(第0个节点)不存数据。 while(p!=NULL&& j<i-1){ p= p->next; j++; } if(p==NULL){ return false; } LNode *s = (LNode *)malloc(sizeof(LNode)); s->data= e; s->next= p->next; p->next= s; return true; } //不带头结点 bool ListInsert(LinkList &L,int i,Elemtype e){ if(i<1) return false; if(i==1){ LNOde *s=(LNode *)malloc(sizeof(LNode)); s->data=e; s-next=L; L=s; return ture; } LNode *p; int j=1; p = L;//第一个节点不是头结点 while(p!=NULL&& j<i-1){ p= p->next; j++; } if(p==NULL){ return false; } LNode *s = (LNode *)malloc(sizeof(LNode)); s->data= e; s->next= p->next; p->next= s; return true; } //前插操作 bool InsertPriorNode(LNode *p,ElemType e){ if(p==NULL) return false; LNode *s = (LNode *)malloc(sizeof(LNode)); if(s==NULL) return false;//内存分配失败 s->next = p->next; p->next = s; s->data = p->data; p->data = e; return ture; } //按位序删除(带头结点) bool ListDelete(LinkList &L int i, ElemType &e){ if(i<1) return false; LNode *p; int j=0; int j=0; p = L;//指向头结点(第0个节点)不存数据。 while(p!=NULL&& j<i-1){ p= p->next; j++; } if(p==NULL){ return false; } if(p->next == NULL){ return false; } LNode *q =p->next; e = q->data; p->next=q->next; free(q); return true; } //删除指定结点 bool DeleteNode(LNode *p){ if(p==NULL){ return false; } LNode *q=p->next; p->data=p->next->data; p->next=q->next; free(q); return true; } //尾插法建立单链表 LinkList List_TailInsert(LinkList &L){ int x; L=(LinkList)malloc(sizeof(LNode)); LNode *s,*r=L; scanf("%d",&x); while(x!=9999){ s=(LNode*)malloc(sizeof(LNode)); s->data=x; r->next=s; r=s; scanf("%d",&x); } r->next=null; return L; } //头插法建立单链表 LinkList List_HeadInsert(LinkList &L){ LNode *s; int x; L=(LinkList)malloc(sizeof(LNode)); L->next=NULL; scanf("%d",&x); while(x!=9999){ s=(LNode*)malloc(sizeof(LNode)); s->data=x; s->next=L->next; L->next=s; scanf("%d",&x); } return L; } //链表逆置(头插法) #include<stdio.h> #include<malloc.h> typedef struct LNode{ int data; struct LNode *next; }LNode,*LinkList; LinkList Reverse(LinkList &L) { LinkList p,q; p=L->next; L->next=NULL; //重新构造单链表 while(p!=NULL) { q=p; p=p->next; q->next=L->next; //头插法 L->next=q; } return L; } int main() { LinkList A = (LinkList)malloc(sizeof(LNode)); LinkList a1 = (LinkList)malloc(sizeof(LNode)); LinkList a2 = (LinkList)malloc(sizeof(LNode)); LinkList a3 = (LinkList)malloc(sizeof(LNode)); LinkList a4 = (LinkList)malloc(sizeof(LNode)); A->next=a1; a1->next=a2; a2->next=a3; a3->next=a4; a4->next=NULL; a1->data=1; a2->data=2; a3->data=3; a4->data=4; LinkList p=A->next; printf("A中元素:"); while(p){ printf("%d ",p->data); p=p->next; } p=Reverse(A); printf("\n单链表逆置之后A中的元素:\n"); for(p=p->next;p!=NULL;p=p->next) { printf("%d ",p->data); } return 0; }
顺序表输出所有元素跟单链表输出时间复杂度一样
双链表
初始化双链表
typedef struct DNode{ ElemType data; struct DNode *prior,*next; }DNode,*DLinklist; bool InitDLinkList(Dlinklist &L){ L=(DNode *)malloc(sizeof(DNode)); if(L==NULL){ return false; } L->prior = NULL; L->next = NULL; return true; } //插入 //关注插入的结点,s的prior和next都要有人 bool InsertNextDNode(DNode *p,DNode *s){ if(p==NUll||s==NULL) return false; s->next=p->next; if(p->next!=NULL) p->next->prior=s; s->prior=p; p->next=s; } //删除p的后继结点 //想要删除谁,关注谁 bool DeleteNextDNode(DNode *p,){ if(p==NUll) return false; DNode *q=p->next; p->next=q->next; if(q->next!=NULL) q->next->prior=p; free(q); return true; } //释放各个结点 void DestoryList(DLinklist &L){ while(L->next!=NULL) DeleteNextDNode(L); free(L); L=NULL; } void testDLinkList(){ DLinklist L; InitDLinkList(L); }
循环单链表
约瑟夫环-
typedef struct LNode{ ElemType data; struct LNode }LNode,*LinkList; //初始化一个循环单链表 bool InitList(LinkList &L){ L = (LNode*)malloc(sizeof(LNode)); if(L==NULL) return false; L->next = L; return true; } //是否为空 bool Empty(LinkList L){ if(L->next ==L) return true; else return false; } //判断结点p是否为循环单链表的表尾结点 bool isTail(LinkList L,LNode *p){ if(p->next==L) return true; else return false; }
循环双链表
typedef struct DNode{ ElemType data; struct DNode *prior,*next; }LNode,*LinkList; //初始化一个循环单链表 bool InitDLinkList(DLinkList &L){ L = (DNode*)malloc(sizeof(DNode)); if(L==NULL) return false; L->prior = L; L->next = L; return true; } //是否为空 bool Empty(LinkList L){ if(L->next ==L) return true; else return false; } //判断结点p是否为循环双链表的表尾结点 bool isTail(DLinkList L,DNode *p){ if(p->next==L) return true; else return false; } //插入 bool InsertNextDNode(DNode *p,DNode *s){ s->next=p->next; p->next->prior=s; s->prior=p; p->next=s; }
静态链表
分配一整片连续的内存空间,各个结点集中安置。
#define MaxSize 10 typedef struct{ ElemType data; int next; }SLinkList[MaxSize]; void testSLinkList(){ struct Node a[MaxSize]; }