一、顺序表
类似数组
1.建立顺序表
void CreatList(SqList *&L,类型 a[],int n)
{
L = (SqList *)malloc(sizeof(SqList));
for(int i=1;i<=n;i++)
{
L->data[i] = a[i];
}
}
2.顺序表的归并(思想与顺序表归并类似,见下面)
顺序表和数组思想一样,也可以用链表做
int UnionList(int A[],int B[])
{
int i=1,j=1,k=0;
while(i <= n && j <= m)
{
if(A[i] < B[j])
{
C[k] = A[i];
k++;
i++;
}
else
{
C[k] = B[j];
k++;
j++;
}
}
while(i <= n)
{
C[k] = A[i];
i++;
k++;
}
while(j <= m)
{
C[k] = B[j];
j++;
k++;
}
return k;
}
二、单链表
需要结构体:
struct nod
{
类型 data;
struct node *next;
}
1.插入节点——头插法(逆序,与输入的顺序相反)
void CreateList(node *&L,类型 a[],int n)
{
struct node *p;
L = (node *)malloc(sizeof(node));
L->next = NULL;
for(int i=1;i<=n;i++)
{
p = (node *)malloc(sizeof(node));
p->data = a[i];
p->next = L->next;
L->next = p;
}
}
2.插入节点——尾插法(正常顺序)
void CreateList(node *&L,类型 a[],int n)
{
struct node *p,*s;
L = (node *)malloc(sizeof(node));
s = L;
for(int i=1;i<=n;i++)
{
p = (node *)malloc(sizeof(node));
p->data = a[i];
s->next = p;
s = p;
}
s->next = NULL;
}
3.输出线性表
void DispList(node *L)
{
node *p;
p = L->next;
while(p!=NULL)
{
printf("%d",p->data);
p = p->next;
}
}
4.删除节点(将链表中重复的元素删除)相同的只留一个
//删除线性表中相同的元素
p = L->next;
while(p!= NULL)
{
q = p;
r = q->next;
while(r!=NULL)
{
if(p->data == r->data) //先保持一个元素不变(P),另一个后移(r,q).
{
q->next = r->next; //把 r 删掉
r = q->next; // r 重新赋值为q 的后继节点
n--;
}
else //若两个不相同,就后移。
{
r = r->next; //r 后移
q = q->next; //q 后移一个
}
}
p = p->next; //都遍历完一次换下一个节点
}
5.删除线性表中数据为e的元素(不只有一个):
p = L;
while(p->next!=NULL)
{
if(p->next->data == e )
{
q = p->next;
p->next = q->next;
free(q);
}
else
p = p->next;
}
6.无序的链表转化成有序链表
void sort(node *&L)
{
struct node *p,*pre,*q;
p = L->next->next; // p 指向L 的第二个数据点
L->next->next = NULL; //构造只含一个数据点的有序单链表
while(p!=NULL)
{
q = p->next; //q 存放p 节点的后继节点的指针
pre = L;
//前一个元素与后一个元素相比,前< 后,则pre后移
while(pre->next !=NULL && pre->next->data < p->data)
pre = pre->next;
//否则:
p->next = pre->next;
pre->next = p;
p = q;
}
//输出链表元素
p = L->next;
while(p!=NULL)
{
printf("%d",p->data);
if(p->next != NULL)
printf(" ");
p = p->next;
}
}
三、双链表
1.建立双向链表
struct nod
{
类型 data;
struct node *next;
struct node *prior;
}
头插法:
void CreateList(node *&L,类型 a[],int n)
{
struct node *p;
L = (node *)malloc(sizeof(node));
L->next = L->prior = NULL;
for(int i=1;i<=n;i++)
{
p = (node *)malloc(sizeof(node));
p->data = a[i];
p->next = L->next;
if(L->next != NULL)
L->next = L->prior = p;
L->next = p;
s->prior = L;
}
}
尾插法:
void CreateList(node *&L,类型 a[],int n)
{
struct node *p,*s;
L = (node *)malloc(sizeof(node));
s = L;
for(int i=1;i<=n;i++)
{
p = (node *)malloc(sizeof(node));
p->data = a[i];
s->next = p;
p->prior = s;
s = p;
}
s->next = NULL;
}
2.输出某一元素的前驱与后继
for(int j=1;j<=m;j++)
{
//输入要查找前驱,后继的元素
scanf("%d",&e);
p = L->next; //第一个元素的位置,首节点是第一个元素
p->prior = NULL; /*一开始做的时候第一个节点的前驱判断不了,因为第一个节点的前驱为 L ,不为空
前驱节点等于L 也不可以,所以直接把 p前驱节点设为空*/
while(p!=NULL)
{
if(p->data == e)
{
if(p->next != NULL && p->prior != NULL)
printf("%d %d\n",p->prior->data,p->next->data);
else if(p->next == NULL && p->prior != NULL)
printf("%d\n",p->prior->data);
else if(p->next != NULL && p->prior == NULL)
printf("%d\n",p->next->data);
}
p = p->next;
}
}
四、循环链表
五、有序表
1.有序链表的归并
用三个顺序表,LA,LB,LC,其中LA,LB存放输入数据,LC存放LA,LB两者之间较小的那个。
void UnionList(node *LA,node *LB)
{
struct node *LC;
struct node *pa = LA->next,*pb = LB->next,*r,*s;
LC = (node *)malloc(sizeof(node));
r = LC;
//将pa(LA),pb(LB)中较小的一个元素放入LC中
while(pa!=NULL && pb!=NULL)
{
if(pa->data < pb->data)
{
s = (node *)malloc(sizeof(node));
s->data = pa->data;
r->next = s;
r = s;
pa = pa->next;
}
else
{
s = (node *)malloc(sizeof(node));
s->data = pb->data;
r->next = s;
r = s;
pb = pb->next;
}
}
//若LA比较长,则比较完后将剩下的元素直接放入LC中
while(pa!=NULL)
{
s = (node *)malloc(sizeof(node));
s->data = pa->data;
r->next = s;
r = s;
pa = pa->next;
}
//同理若LB比较长,则比较完后将剩下的元素直接放入LC中
while(pb!=NULL)
{
s = (node *)malloc(sizeof(node));
s->data = pb->data;
r->next = s;
r = s;
pb = pb->next;
}
r->next = NULL;
s = LC->next;
while(s!=NULL)
{
printf("%d ",s->data);
s = s->next;
}
}