思维导图:点我
一、顺序表
1. 数据结构
-
静态存储类型
#define MaxSize 10 typedef struct { ElemType data[MaxSize]; int length; } SqList;
-
动态存储类型
typedef struct { ElemType *data; int MaxSize,length; } SqList;
-
动态声明
L.data=(ElemType*)malloc(sizeof(ElemType)*InitSize);// C L.data=new ElemType[InitSize];// C++
-
插入
bool ListInsert(SqList &L,int i,ElemType e) { if(i<1||i>L.length+1) return false; if(L.length>=MaxSize) return false; 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 ListDeleteByPosition(SqList &L,int i,ElemType &e) { if(i<1||i>L.length) return false; if(L.length<=0) return false; 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 LocateElem(SqList L,ElemType e) { for(int i=0; i<L.length; ++i) if(L.data[i]==e) return i+1; return 0; }
-
按值删除
bool ListDeleteByValue(SqList &L,ElemType e) { for(int i=0; i<L.length; ++i) if(L.data[i]==e) { for(int j=i; j<L.length-1; ++j) L.data[j]=L.data[j+1]; break; } return true; }
2. 矩阵的压缩处理
矩阵的压缩处理实际上就是将二维或更高维矩阵存储在一维矩阵里,通常用顺序表来实现,下面简单说明几个二维矩阵的压缩举例:
- 普通矩阵
k = { i ( i − 1 ) 2 + j − 1. ( i ≥ j ) 即 下 三 角 区 和 主 对 角 线 元 素 j ( j − 1 ) 2 + i − 1. ( i < j ) 即 上 三 角 区 元 素 k=\left\{\begin{matrix}\frac{i(i-1)}{2}+j-1.(i\ge j)即下三角区和主对角线元素\\\frac{j(j-1)}{2}+i-1.(i<j)即上三角区元素\end{matrix}\right. k={2i(i−1)+j−1.(i≥j)即下三角区和主对角线元素2j(j−1)+i−1.(i<j)即上三角区元素 - 下三角矩阵
k = { i ( i − 1 ) 2 + j − 1. ( i ≥ j ) 即 下 三 角 区 和 主 对 角 线 元 素 n ( n + 1 ) 2 . ( i < j ) 即 上 三 角 区 元 素 k=\left\{\begin{matrix}\frac{i(i-1)}{2}+j-1.(i\ge j)即下三角区和主对角线元素\\\frac{n(n+1)}{2}.(i<j)即上三角区元素\end{matrix}\right. k={2i(i−1)+j−1.(i≥j)即下三角区和主对角线元素2n(n+1).(i<j)即上三角区元素 - 上三角矩阵
k = { ( i − 1 ) ( 2 n − i + 2 ) 2 + ( j − i ) . ( i ≥ j ) 即 上 三 角 区 和 主 对 角 线 元 素 n ( n + 1 ) 2 . ( i < j ) 即 下 三 角 区 元 素 k=\left\{\begin{matrix}\frac{(i-1)(2n-i+2)}{2}+(j-i).(i\ge j)即上三角区和主对角线元素\\\frac{n(n+1)}{2}.(i<j)即下三角区元素\end{matrix}\right. k={2(i−1)(2n−i+2)+(j−i).(i≥j)即上三角区和主对角线元素2n(n+1).(i<j)即下三角区元素 - 三对角矩阵
k = 2 i + j − 3 i = ⌊ ( k + 1 ) / 3 + 1 ⌋ j = k − 2 i + 3 k=2i+j-3\\i=\left \lfloor(k+1)/3+1\right \rfloor\\j=k-2i+3 k=2i+j−3i=⌊(k+1)/3+1⌋j=k−2i+3 - 稀疏矩阵(三元组表示):
i | j | v |
---|---|---|
0 | 1 | 6 |
二、链表
1. 单链表
-
结点类型
typedef struct LNode { ElemType data; struct LNode *next; } LNode, *LinkList;
-
头插法建立单链表
LinkList List_HeadInsert(LinkList &L,SqList q) { LNode *s; L=(LinkList)malloc(sizeof(LNode)); L->next=NULL; for(int i=0; i<q.length; ++i) { s=(LinkList)malloc(sizeof(LNode)); s->data=q.data[i]; s->next=L->next; L->next=s; } return L; }
-
尾插法建立单链表
LinkList List_TailInsert(LinkList &L,SqList q) { L=(LinkList)malloc(sizeof(LNode)); LNode *s,*r=L; for(int i=0; i<q.length; ++i) { s=(LinkList)malloc(sizeof(LNode)); s->data=q.data[i]; r->next=s; r=s; } r->next=NULL; return L; }
-
按序号查找表结点
LNode *GetElem(LinkList L,int i) { int j=1; LNode *p=L->next; if(i==0) return L; if(i<1) return NULL; while(p&&j<i) { p=p->next; j++; } return p; }
-
按值查找表结点
LNode *LocateElem(LinkList L,ElemType e) { LNode *p=L->next; while(p!=NULL&&p->data!=e) p=p->next; return p; }
-
按位置插入结点
bool NodeInsertByPosition(LinkList &L,int i,ElemType e) { LNode *p,*s; p=GetElem(L,i-1); s=(LinkList)malloc(sizeof(LNode)); s->data=e; s->next=p->next; p->next=s; return true; }
-
对某一结点进行前插
bool NodeInsertToFront(LNode *&p,ElemType e) { LNode *s; s=(LinkList)malloc(sizeof(LNode)); s->data=p->data; s->next=p->next; p->data=e; p->next=s; return true; }
-
按位置删除结点
bool NodeDeleteByPosition(LinkList &L,int i,ElemType &e) { LNode *p,*s; p=GetElem(L,i-1); s=p->next; e=s->data; p->next=s->next; free(s); return true; }
-
按值删除结点
bool NodeDeleteByValue(LinkList &L,ElemType e) { LNode *p=L,*s; while(p->next->data!=e&&p->next!=NULL) p=p->next; s=p->next; p->next=s->next; free(s); return true; }
-
求表长操作
int GetLength(LinkList L) { LNode *p=L->next; int length=0; while(p!=NULL) { p=p->next; length++; } return length; }
2. 双链表
-
存储类型
typedef struct DNode { ElemType data; struct DNode *prior,*next; } DNode,*DLinklist;
-
头插法建立双链表
DLinklist List_HeadInsert(DLinklist &L,SqList q) { DNode *s; L=(DLinklist)malloc(sizeof(DNode)); L->next=NULL; L->prior=NULL; for(int i=0; i<q.length; ++i) { s=(DLinklist)malloc(sizeof(DNode)); s->data=q.data[i]; s->next=L->next; s->prior=L; if(s->next!=NULL) s->next->prior=s; L->next=s; } return L; }
-
尾插法建立链表
DLinklist List_TailInsert(DLinklist &L,SqList q) { L=(DLinklist)malloc(sizeof(DNode)); L->prior=NULL; DNode *s,*r=L; for(int i=0; i<q.length; ++i) { s=(DLinklist)malloc(sizeof(DNode)); s->data=q.data[i]; r->next=s; s->prior=r; r=s; } r->next=NULL; return L; }
-
按序号查找结点
DNode *GetElem(DLinklist L,int i) { int j=1; DNode *p=L->next; if(i==0) return L; if(i<1) return NULL; while(p&&j<i) { p=p->next; j++; } return p; }
-
按值查找结点
DNode *LocateElem(DLinklist L,ElemType e) { DNode *p=L->next; while(p!=NULL&&p->data!=e) p=p->next; return p; }
-
按位置插入结点
bool NodeInsertByPosition(DLinklist &L,int i,ElemType e) { DNode *p,*s; p=GetElem(L,i-1); s=(DLinklist)malloc(sizeof(DNode)); s->data=e; s->next=p->next; s->prior=p; s->next->prior=s; p->next=s; return true; }
-
对某一结点进行前插
bool NodeInsertToFront(DNode *&p,ElemType e) { DNode *s; s=(DLinklist)malloc(sizeof(DNode)); s->data=p->data; s->next=p->next; s->next->prior=s; s->prior=p; p->data=e; p->next=s; return true; }
-
按位置删除结点
bool NodeDeleteByPosition(DLinklist &L,int i,ElemType &e) { DNode *p,*s; p=GetElem(L,i-1); s=p->next; e=s->data; p->next=s->next; s->next->prior=p; free(s); return true; }
-
按值删除结点
bool NodeDeleteByValue(DLinklist &L,ElemType e) { DNode *p=L,*s; while(p->next->data!=e&&p->next!=NULL) p=p->next; s=p->next; p->next=s->next; s->next->prior=p; free(s); return true; }
-
求表长度
int GetLength(DLinklist L) { DNode *p=L->next; int length=0; while(p!=NULL) { p=p->next; length++; } return length; }
3. 循环链表
尾结点next
指针指向头结点的单链表
4. 循环双链表
头结点prior
指针指向尾结点,尾结点next
指针指向头结点的双链表
5. 静态链表
本质上是利用顺序表构造的一个单链表,具有单链表的特点以及顺序表不能扩充的特点
typedef struct
{
ElemType data;
int next;// -1表示结束,-2表示空
} SLinkList[MaxSize];