线性表
1. 概念
线性表是具有相同特性的数据元素的一个有限序列。
1.1. 逻辑特征
线性表中的元素位置是有序的,这种位置关系构成了一种线性关系,因此线性表是一个线性结构,即对于至少含有一个数据元素的线性表,除起始元素外均有且仅有一个前驱,除终端元素外均有且仅有一个后继。若线性表中的元素按照某种顺序排列,则称该线性表为有序表。
1.2. 存储结构
有顺序和链式两种存储结构,分别称为顺序表和链表。链表的每个节点包含数据域和指针域,第一个节点的存储位置称为头指针,如果链表带有头结点,那头指针为头结点的地址,否者为起始节点。
2. 顺序表
定义
#define MaxSize 50
typedef struct
{
ElemType data[MaxSize];
int length;
}SqList;
初始化顺序表
void InitList(SqList &L)
{
L.length = 0;
}
求指定位置元素
int GetElem(SqList L, int i, ElemType &e)
{
if(i < 1 || i > L.length)
return 0;
e = L.data[i-1];
return 1;
}
按元素查找
int LocateElem(SqList L, int &n, ElemType e)
{
if(L == NULL)
return 0;
int i = 0;
while(L.data[i] != e && i < L.length)
i++;
if(i == L.length)
return 0;
n = i+1;
return 1;
}
插入数据元素(插到第 i 个位置上)
int ListInsert(SqList &L, ElemType e, int i)
{
if(i < 1 || i > L.length+1)
return 0;
L.length++;
int j;
for(j = L.length-1; j >= i; j--)
L.data[j] = L.data[j-1];
L.data[j] = e;
return 1;
}
删除数据元素
int ListDelete(SqList &L, int i, ElemType &e)
{
if(i < 1 || i > L.length)
return 0;
e = L.data[i-1];
for(int j = i-1; j < L.length-1; j++)
L.data[j] = L.data[j+1];
L.lenght--;
return 1;
}
有序顺序表的归并算法
void MergeList(SqList L1, SqList L2, SqList &L3)
{
int i = 0, j = 0, k = 0;
while(i < L1.length && j < L2.length){
if(L1.data[i] < L2.data[j]){
L3.data[k] = L1.data[i];
k++; i++;
}else if(L1.data[i] > L2.data[j]){
L3.data[k] = L2.data[j];
k++; j++;
}else{
L3.data[k] = L1.data[i];
k++; i++; j++;
}
}
while(i < L1.length){
L3.data[k] = L1.data[i];
k++; i++;
}
while(j < L2.length){
L3.data[k] = L1.data[j];
k++; j++;
}
L3.length = k;
}
3. 单链表
定义
typedef struct LNode{
ElemType data;
LNode *next;
}LinkList;
头插法建立单链表(次序与原来次序相反)
void CreateListF(LinkList *&L, ElemType a[], int n)
{
LinkList *s; int i;
L = (LinkList *)malloc(sizeof(LinkList)); //创建头结点
L->next = NULL;
for(i = 0, i < n, i++){
s = (LinkList *)malloc(sizeof(LinkList));
s->data = a[i];
s->next = L->next;
L->next= s;
}
}
尾插法建立单链表(次序与原来次序相同)
void CreateListR(LinkList *&L, ElemType a[], int n)
{
LinkList *s, *r; int i;
L = (LInkList *)malloc(sizeof(LinkList));
L->next = NULL;
r = L;
for(i=0, i<n, i++){
s = (LinkList *)malloc(sizeof(LinkList));
s->data = a[i];
r->next = s;
r = s;
}
r->next = NULL;
}
按元素查找
int LocateElem(LinkList *L, ElemType e)
{
LinkList *p = L->next;
int i = 1;
while(p!=NULL && p->data!=e){
p = p->next;
i++;
}
if(p==NULL)
return 0;
else
return i;
}
将 e 插入到单链表的第 i 个节点位置上
int InsertElem(LinkList *&L, ElemType e, int n)
{
LinkList *p = L, *s; // p 为第一个节点位置的前一个节点
int j = 0;
while(p!=NULL && j<n-1){
p = p->next;
j++;
}
if(p!=NULL){
s = (LinkList *)malloc(sizeof(LinkList));
s->data = e;
s->next = p->next;
p->next = s;
return 1;
}
else
return 0;
}
删除第 i 个节点位置上的元素
int DeleteElem(LinkList *&L, ElemType &e, int n)
{
LinkList *p = L, *q; // p 为第一个节点位置的前一个节点
int j = 0;
while(p!=NULL && j<n-1){
p = p->next;
j++;
}
if(p!=NULL && p->next!=NULL){
q = p->next;
p->next = q->next;
free(q);
return 1;
}
else
return 0;
}
有序单链表的归并(新建单链表)
void MergeList1(LinkList *L1, LinkList *L2, LinkList *&L3)
{
LinkList *s1 = L1->next, *s2 = L2->next, *r, *s;
L3 = (LinkList *)malloc(sizeof(LinkList));
L3->next = NULL;
r = L3;
while(s1!=NULL && s2!=NULL){
if(s1->data < s2->data){
s = (LinkList *)malloc(sizeof(LinkList));
s->data = s1->data;
r->next = s;
r = s; s1 = s1->next;
}else if(s1->data > s2->data){
s = (LinkList *)malloc(sizeof(LinkList));
s->data = s2->data;
r->next = s; s2 = s2->next;
r = s;
}else{
s = (LinkList *)malloc(sizeof(LinkList));
s->data = s1->data;
r->next = s;
r = s; s1 = s1->next; s2 = s2->next;
}
}
if(s2!=NULL)
s1 = s2;
while(s1!=NULL){
s = (LinkList *)malloc(sizeof(LinkList));
s->data = s1->data;
r->next = s;
r = s; s1 = s1->next;
}
r->next = NULL;
}
有序单链表的归并(要求空间复杂度为 O(1) ,即舍弃原来的两个单链表)
void MergeList(LinkList *L1, LinkList *L2, LinkList *&L3)
{
LinkList *p = L1->next, *q = L2->next;
L3 = (LinkList *)malloc(sizeof(LinkList));
L3 = L1;
free(L2);
r = L3;
while(p!=NULL && q!=NULL){
if(p->data < q->data){
r->next = p;
p = p->next;
}
else if(p->data > q->data){
r->next = q;
q = q->next;
}
else{
r->next = p;
p = p->next;
q = q->next;
}
}
if(q!=NULL)
p = q;
r->next = p;
}
4. 双链表
双链表头尾不相接
定义
typedef struct DLinkList{
ElemType data;
DLinkList *next;
DLinkList *prior;
}DLinkList;
头插法建立双链表
void CreateDListF(DLinkList *&L, ElemType a[], int n)
{
DLinkList *s;
L = (DLinkList *)malloc(sizeof(DLinkList));
L->next = L->prior = NULL;
for(int i=0; i<n; i++){
s = (DLinkList *)malloc(sizeof(DLinkList));
s->data = a[i];
s->next = L->next;
if(L->next!=NULL)
L->next->prior = s;
L->next = s;
s->prior = L;
}
}
尾插法建立双链表
void CreateDListR(DLinkList *&L, ElemTyoe a[], int n)
{
DLinkList *s, *r;
L = (DLinkList *)malloc(sizeof(DLinkList));
L->next = L->prior = NULL;
r = L;
for(int i=0; i<n; i++){
s = (DLinkList *)malloc(sizeof(DLinkList));
s->data = a[i];
r->next = s;
s->prior = r;
r = s;
}
r->next = NULL;
}
查找指定元素节点
int FindNode(DLinkList *L, ElemType e)
{
DLinkList *p = L->next;
int i = 1;
while(p!=NULL && p->data != e){
p = p->next;
i++;
}
if(p!=NULL)
return i;
else
return 0;
}
将 e 插入第 n 个节点位置
int InsertNode(DLinkList *&L, ElemType e, int n)
{
DLinkList *p, *s;
int i = 0;
p = L;
while(p!=NULL && i<n-1){
p = p->next;
i++;
}
if(p!=NULL){
s = (DLinkList *)malloc(sizeof(DLinkList));
s->data = e;
s->next = p->next;
s->prior = p;
if(p->next!=NULL){
p->next->prior = s;
p->next = s;
}
return 1;
}
else
return 0;
}
删除第 n 个节点位置的元素
int DeleteNode(DLinkList *&L, ElemType e, int n)
{
DLinkList *p, *q;
int i = 0;
p = L;
while(p!=NULL && i<n-1){
p = p->next;
i++;
}
if(p!=NULL){
q=p->next;
if q==NULL;
return 0;
p->next = q->next;
if(q->next!=NULL)
q->next->prior = p;
free(q);
return 1;
}
else
return 0;
}
5. 循环链表
定义
typedef struct LNode{
ElemType data;
next LNode *next;
}LinkList;
头插法建立循环链表
void CreateListF(LinkList *&L, ElemType a[], int n)
{
LinkList *s;
int i;
L = (LinkList *)malloc(sizeof(LinkList));
L->next = L;
for(i=0; i<n; i++){
s = (LinkList *)malloc(sizeof(LinkList));
s->data = a[i];
s->next = L->next;
L->next = s;
}
}
尾插法建立循环链表
void CreateListR(LinkList *&L, ElemType a[], int n)
{
LinkList *s, *r;
int i;
L = (LinkList *)malloc(sizeof(LinkList));
L->next = L;
r = L;
for(i=0; i<n; i++){
s = (LinkList *)malloc(sizeof(LinkList));
s->data = a[i];
r->next = s;
r = s;
}
r->next = L;
}
查找元素值为 e 的节点
int FindNode(LinkList *L, ElemTpye e)
{
LinkList *p = L->next;
int i = 1;
while(p!=L && p->data = e){
p = p->next;
i++;
}
if(p==L)
return 0;
else
return i;
}
6. 静态链表
struct Node{
typename data; // 数据域
int next; // 存放下一个结点的数组下标
xxx; // 结点的某些性质
}
7. 申请动态内存函数
7.1. C 语言
malloc 函数:typename* p=(typename*)malloc(sizeof(typename));
对应的内存释放函数 free :free(p);
7.2. C++
new 函数:typename* p=new typename;
对应的内存释放函数 delete :delete(p);