线性表
零个或多个数据元素的有限序列,线性表中的元素是一对一的关系,除了第一个元素和最后一个元素外,其他元素都是首尾相接的。线性表有两种存储方式,一种是顺序存储结构,另一种是链式存储结构。
顺序存储结构
指用一段地址连续的存储单元依次存储线性表的数据元素。
优点
- 无需为表示元素间的逻辑关系而增加额外的存储空间
- 随机查询元素,即查询元素的时间复杂度为O(1)
缺点
- 插入和删除需要移动大量元素,最坏为O(n)
- 线性表长度变化较大时,不确定存储空间容量
- 产生存储空间碎片
常用的数组就是典型的线性表顺序存储结构
链式存储结构
指用一组任意的存储单元存储线性表的数据元素,这组存储单元可能连续,也可能不连续。为了表示元素之间的逻辑关系,对于元素来说,不仅要存储本身的数据外,还要存储一个指示其后继元素的位置。存储数据元素的域称为数据域,存储后继元素位置的域称为指针域。这个元素称为结点。
只包含一个指针域的链表称为单链表
代码
结点定义
typedef struct LinkList
{
ElementType data;
struct LinkList* next;
}Node, LinkList, *LinkListPtr;
类定义
#include <stdio.h>
#define OK 1
#define ERROR 0
typedef int Status;
typedef int ElementType;
typedef struct LinkList
{
ElementType data;
struct LinkList* next;
}Node, LinkList, *LinkListPtr;
LinkListPtr createWithHead(int n)
{
LinkListPtr list, node;
ElementType data;
list = (LinkListPtr)malloc(sizeof(Node));
list->next = NULL;
for(int i = 0; i < n; ++i)
{
node = (LinkListPtr)malloc(sizeof(Node));
scanf("%d", &data);
node->data = data;
node->next = list->next;
list->next = node;
}
return list;
}
LinkListPtr createWithTail(int n)
{
LinkListPtr list, node, tail;
ElementType data;
list = (LinkListPtr)malloc(sizeof(Node));
list->next = NULL;
tail = list;
for(int i = 0; i < n; ++i)
{
node = (LinkListPtr)malloc(sizeof(Node));
scanf("%d", &data);
node->data = data;
node->next = NULL;
tail->next = node;
tail = tail->next;
}
return list;
}
Status insertCertainPos(LinkListPtr list, int pos, ElementType data)
{
LinkListPtr p = list, node;
int i = 0;
while(p && i++ < pos - 1)
p = p->next;
if(!p || i > pos)
return ERROR;
node = (LinkListPtr)malloc(sizeof(Node));
node->data = data;
node->next = p->next;
p->next = node;
return OK;
}
Status deleteCertainPos(LinkListPtr list, int pos, ElementType data)
{
LinkListPtr p = list, q;
int i = 0;
while(p && i++ < pos - 1)
p = p->next;
if(!p || i > pos)
return ERROR;
q = p->next;
data = q->data;
p->next = q->next;
free(q);
return OK;
}
Status clearList(LinkListPtr list)
{
LinkListPtr p = list->next, q;
q = p;
while(p)
{
list->next = p->next;
free(p);
p = list->next;
}
list->next = NULL;
return OK;
}
Status reverse(LinkListPtr list)
{
LinkListPtr p = list->next, q, r;
q = p->next;
r = q->next;
p->next = NULL;
while(r != NULL)
{
q->next = p;
p = q;
q = r;
r = r->next;
}
q->next = p;
list->next = q;
return OK;
}
Status printLinkList(LinkListPtr list)
{
LinkListPtr p = list->next, q;
while(p)
{
printf("%d\t", p->data);
p = p->next;
}
printf("\n");
return OK;
}
int main()
{
LinkListPtr listWithHead = createWithHead(5);
printLinkList(listWithHead);
LinkListPtr listWithTail = createWithTail(5);
printLinkList(listWithTail);
Status result = insertCertainPos(listWithTail, 1, 0);
printLinkList(listWithTail);
ElementType data;
result = deleteCertainPos(listWithTail, 1, data);
printLinkList(listWithTail);
clearList(listWithHead);
printLinkList(listWithHead);
reverse(listWithTail);
printLinkList(listWithTail);
return 0;
}