一.线性表的结构体定义
1. 顺序表的结构体定义
#define maxSize 100
typedef struct
{
int data[maxSize]; //存放顺序表元素的数组
int length; //存放顺序表的长度
}Sqlist; //顺序表类型的定义
2. 单链表结点定义
typedef struct LNode
{
int data; //data中存放结点数据域
struct LNode *next; //指向后继节点的指针
}LNode; //定义单链表结点类型
3. 双链表结点定义
typedef struct DLNode
{
int data; //data中存放结点的数据域
struct DLNode *prior; //指向前驱结点的指针
struct DLNode *next; //指向后继结点的指针
}DLNode; //定义双链表结点类型
二.顺序表的操作
1.已知一个顺序表L,其中的元素递增有序排列,设计一个算法,插入一个 元素x(x为int型)后保持该顺序表仍然递增有序排列(假设插入操作总能成功)
Note1:找出可以让顺序表保持有序的插入位置
Note2:将Note1中找出的位置上以及其后的元素往后移动一个位置,然后将x放置腾出的位置上
int findElem(Sqlist L,int x) //本函数返回第一个比x大的元素的位置
{
int i;
for(i=0;i<L.length;++i)
{
if(x < L.data[i])
{
return i; //循环找到第一个比x大的元素的位置
}
}
return i; //如果找不到比x大的元素,此时应该将x插入表尾位置,又因为for循环执行结束的条件是i=L.length,也就是顺序表中最后一个元素的后一个位置,即要插入新元素的位置
}
void insertElem(Sqlist &L,int x) //因为L本身要发生变化,所以要用引用型
{
int p,i; //p为要插入元素的位置,i循环变量
p=findElem(L,x);
for(i=L.length-1;i>=p;--i) //将p位置及以后的元素都往后移动一个位置
{
L.data[i+1]=L.data[i];
}
L.data[p]=x; //将x放在插入位置p上
L.length++; //顺序表多了一个元素,表长增加1
}
2.删除顺序表L中下标为p(0≤p≤length-1)的元素,成功返回1,否则返回0并将被删除元素的值赋给e
Note1:只需将p后面的元素都往前移动一个位置覆盖前面的元素即可,最后表长-1
int deleteElem(Sqlist &L,int p,int e)
{
int i;
if(p<0||p>L.length-1) //如果p位置非法,则删除失败返回0
return 0;
e=L.data[p]; //将被删除元素的值赋给e
for(i=p;i<L.length-1;++i)
{
L.data[i]=L.data[i+1]; //将p后面的元素往前移动一个位置覆盖前面的元素
}
L.length--; //表长-1
return 1; //删除成功返回1
}
三.单链表的操作
1.A和B是两个单链表(带表头结点),其中元素递增有序。设计一个算法,将A和B归并成一个按元素值非递减有序的链表C,C由A和B中的结点组成
Note1:使用尾插法使得新得到的链表C依然递增有序
Note2:链表A与链表B递增有序,从头开始扫描进行比较选取较小的插入链表C
Note3:链表A(链表B)已经插完,只需将剩余链表A(链表B)链接到C即可
void merge(LNode *A,LNode *B,LNode *&C)
{
LNode *p = A->next; //p跟踪A的最小值点
LNode *q = B->next; //q跟踪B的最小值点
LNode *r; //r始终指向C的终端结点
C=A; //用A的头结点来做C的头结点
C->next = NULL;
free(B); //B的头结点已无用,删去
r=C; //r指向C,因为此时头结点也是终端结点
while(p!=NULL && q!=NULL)
{
if(p->data <= q->data) //p结点的值小于q结点的值 插入p
{
r->next = p;
p = p->next;
r = r->next;
}
else //q结点的值小于p结点的值 插入q
{
r->next = q;
q = q->next;
r = r->next;
}
}
r->next = NULL;
if(p != NULL)
{
r->next = p;
}
if(q != NULL)
{
r->next = q;
}
}
2.尾插法
void createlistRear(LNode *&C,int a[],int n)
{
LNode *s,*r; //s用来指向新申请的结点,r始终指向C的终端结点
int i;
C = (LNode *)malloc(sizeof(LNode)); //申请C的头结点空间
C->next = NULL;
r=C; //r始终指向终端结点,此时头结点就是终端结点
for(i=0;i<n;++i)
{
s = (LNode *)malloc(sizeof(LNode));
s->data = A[i];
r-next = s;
r = r->next;
}
r->next = NULL;
}
3.头插法
void createlistHead(LNode *&C,int a[],int n)
{
LNode *s;
int i;
C = (LNode *)malloc(sizeof(LNode));
C->next = NULL;
for(i=0;i<n;++i)
{
s = (LNode *)malloc(sizeof(LNode));
s->data = a[i];
s->next = C->next;
C->next = s;
}
}
4.归并成递减的单链表
void merge(LNode *A,LNode *B,LNode *&C)
{
LNode *p = A->next;
LNode *q = B->next;
LNode *s; //用s来接收新的结点
C = A;
C->next = NULL;
free(B);
while(p!=NULL && q!=NULL)
{
if(p->data < q->data)
{
s = p;
p = p->next;
s->next = C->next;
C->next = s;
}
else
{
s = q;
q = q->next;
s->next = C->next;
C->next = s;
}
}
//必须将剩余元素逐个插入C的头部才能得到最终的递减序列
while(p!=NULL)
{
s = p;
p = p->next;
s->next = C->next;
C->next = s;
}
while(q!=NULL)
{
s = q;
q = q->next;
s->next = C->next;
C->next = s;
}
}
5.查找链表C(带头结点)中是否存在一个值为x的结点,若存在则删除该结点并返回1,否则返回0
Note1:定义一个指针变量p遍历单链表每遇到一个新结点就检测其值是否为x
Note2:定义一个指针变量q来接收被删除的结点
int findAndDelete(LNode *C,int x)
{
LNode *p,*q;
p = C;
//查找开始
while(p->next != NULL)
{
if(p->next->data == x)
break;
p = p->next;
}
//查找结束
if(p->next == NULL) //当p来到最后一个结点,也就是while循环结束条件(p->next==NULL)
return 0;
else
{
//删除开始
q = p->next;
p->next = p->next->next;
free(q);
//删除结束
return 1;
}
}
四.双链表的操作
1.采用尾插法建立双链表
void createDlistRear(DLNode *&L,int a[],int n)
{
DLNode *s,*r; //s接收新结点,r始终指向终端结点
int i;
L = (DLNode *)malloc(sizeof(DLNode));
L->prior = NULL;
L->next = NULL;
r=L;
for(i=0;i<n;++i)
{
s = (DLNode *)malloc(sizeof(DLNode));
s->data = a[i];
//尾插法
r->next = s;
s->prior = r;
r = r->next;
}
r->next = NULL;
}
2.查找结点的算法,找到返回结点指针,否则返回NULL
DLNode* findNode(DLNode *C,int x)
{
DLNode *p = C->next;
while(p != NULL)
{
if(p->data == x)
break;
p=p->next;
}
return p; //如果找到,p中内容是结点地址(循环因break结束)如果没找到,则p中内容是NULL(循环因p等于NULL而结束)
}
3.插入结点算法 p之后插入s
s->next = p->next;
s->prior = p;
p->next = s;
s-next-prior = s;
4.删除结点算法 删除p结点的后继节点
q = p->next;
p->next = q-next;
q->next->prior = p;
free(q);