线性表
线性表我们分为顺序表和链表,两种表各有优劣势。
顺序表:所占空间一开始就固定,满了就放不下了,但存相同的数据,所占内存比链表好。
链表:可以一直创立下去,是我们比较常用的,但所占的多余空间较多。
我们的链表所使用的一些函数是大多数链表都通用的,现在我们用一个实例说明一下。
线性表实例
要求实现一个合并函数,实现对有序单循环链表tail1和tail2的合并,要求合并时实现去重操作,即合并后的链表中没有重复的元素,并且合并后的链表为递增有序链表。
#include<stdio.h>
#include<stdlib.h>
typedef int DataType;
struct Node //定义线性表类型
{
DataType data;
struct Node * next;
};
typedef struct Node Node; //大量使用typedef,等封装比较容易。
typedef struct Node *PNode;
typedef struct Node *LinkList;
PNode createEmptyLinkedList() //建立链表,返回链头。
{
PNode current;
current = (PNode)malloc(sizeof(Node));
current->next = NULL;
current->data = -1;
return current;
}
int IsNull_Link(LinkList llist) //判空。
{
return(llist->next == NULL);
}
PNode buildCircularLinkedList(int n, PNode tail) //建起链表,把链表链下去。
{
PNode current=NULL, prev;
prev = tail;
for (int i = 0; i < n; i++)
{
current = (PNode)malloc(sizeof(Node));
current->next = NULL;
scanf("%d", ¤t->data);
prev->next = current;
prev = current;
}
current->next = tail->next;
tail->next = current;
return tail;
}
PNode mergeNDeduplicateList(PNode tail1, PNode tail2) //把我们输入的两个有序链表合成一个有序链表。
{
PNode p=tail1->next,q=tail2->next,a,b,c,d;
int k=0;
a=p->next;
b=p->next;
c=p->next;
d=p->next;
p->next=q->next;
q->next=NULL;
while(b->next!=NULL)
{ if(c==b)
{
b=b->next;
}
while(a!=b)
{
k=0;
if(a->data==b->data)
{
c->next=b->next;
free(b);
b=c->next;
k=1;
break;
}
a=a->next;
}
a=d;
if(k==0)
{
c=c->next;
b=b->next;
}
}
q->next=d;
tail1->next=q;
return tail1;
}
void printCircularLinkedList(PNode tail) //输出链表的内容。
{
PNode current, last;
last = tail->next;
current = last->next;
do
{
printf("%d ", current->data);
current = current->next;
} while (current != last->next);
}
void DestoryList_Link(LinkList tail) //用完了链表释放所占空间。
{
PNode pre = tail->next;
PNode p = pre->next;
while (p != tail)
{
free(pre);
pre = p;
p = pre->next;
}
free(pre);
free(tail);
}
int main()
{
PNode list1, list2;
int list1_number, list2_number;
list1 = createEmptyLinkedList(); //建立第一个链表的表头
list2 = createEmptyLinkedList(); //建立第二个链表的表头
scanf("%d", &list1_number);
buildCircularLinkedList(list1_number, list1); //建起第一个链表
scanf("%d", &list2_number);
buildCircularLinkedList(list2_number, list2); //建起第二个链表
list1 = mergeNDeduplicateList(list1, list2); //合成一个链表
printCircularLinkedList(list1);
return 0;
}
我的测试用例为
5
1 2 2 3 6
6
2 6 6 9 15 19
结果为