一、线性表和单链表的关系
1、线性表
- 线性表是信息表的一种形式,表中数据元素之间满足线性关系(或线性结构),是一种最基本、最简单的数据结构类型。
线性表的定义及运算:
线性表的定义是描述其逻辑结构,而运算是讨论在线性表上进行的查找、插入、删除等操作。
- 定义:线性表(Linear List)是包含若干数据元素的一个线性序列,记为:L=(a0,........ai-1aiai+1.........an-1)
- 线性表的特征:
1)对非空表,a0是表头,无前驱。
1)an-1是表尾,无后继。
1)其他的每个元素ai有且且有一个直接前驱(ai-1)和一个直接后继(ai+1)
2、线性表的链式存储结构
- 下面讨论线性表的链式存储结构,即链表。
(1)单链表结构
将线性表L中各元素分布在存储器的不同存储块,称为节点,通过地址或指针建立它们之间的联系 ,所得到的存储结构为链表结构。表中元素ai的节点形式如图所示:
其中,节点的data域存放数据元素ai,而next域是一个指针,指向ai的直接后继ai+1所在的节点。于是,线性表L的结构如图所示:
例子:
- 线性表的链式存储结构
(1)节点类型描述:
typedef struct node_t
{
data_t data; //节点的数据域
struct node_t * next;//节点的后继指针域
}linknode_t,*linklist_t;
linknode_t A;
linklist_t p = &A;
- 则结构变量A为所描述的节点,而指针表量P为指向此类型节点的指针(p的值为节点的地址),如图所示:
二、单链表概述
1、单链表的两种创建方式
linklist * list_create(void)
{
linklist * q;
q = (linklist*)malloc(sizeof(linklist));
if(q == NULL)
{
printf("Linklist malloc faile !!");
return NULL;
}
q->data = 0;
q->next = NULL;
return q;
}
linklist * list_create2(void)
{
linklist * q;
int n;
q = (linklist*)malloc(sizeof(linklist));
if(q == NULL)
{
printf("Linklist malloc faile !!");
return NULL;
}
q->data = 0;
q->next = NULL;
while(1)
{
printf("please input list(-1 EXIT) : ");
scanf("%d",&n);
if(n==-1)break;
list_Head_insert(q,n);
}
return q;
}
2、单链表的遍历
void Show_LinkList(linklist * L)
{
linklist * p;
if(L == NULL)
{
printf("Linklist is NULL !!!");
return;
}
p = L;
while(p->next)
{
printf("%d ",p->next->data);
p = p->next;
}
}
3、单链表的插入
int list_Head_insert(linklist * L,data_t x)
{
linklist * q;
if(L == NULL)
{
printf("Linklist is NULL !!!");
return -1;
}
q = (linklist*)malloc(sizeof(linklist)); //创建动态空间
q->data=x;
q->next = L->next;
L->next = q;
return 0;
}
int list_insert(linklist * L,data_t x,data_t pos)
{
linklist * p,*q;
int i=0;
if(L == NULL)
{
printf("Linklist is NULL !!!! \n");
return -1;
}
if(pos<0)
{
printf("pos<0!!");
return -1;
}
p = L;
q = (linklist*)malloc(sizeof(linklist));
if(q == NULL)
{
printf(" Insert Faile !!!");
return -1;
}
q->data = x; //将要插入的数据放入节点中,以节点的形式插入链表中
if(pos == 0) //头插特殊处理
{
q->next = p->next;
p->next = q;
}else
{
while(i<pos) //移动辅助指针 至插入的位置的前节点
{
i++;
p=p->next;
}
q->next = p->next; // 要插入的节点的next 指向 辅助指针指向的节点
p->next = q; //将辅助指针的next指向要插入的节点
}
return 0;
}
4、单链表的删除
int DeleteLinkList(linklist * L,data_t x)
{
linklist * q;
linklist * p;
if(L == NULL)
{
printf("Linklist is NULL'!!");
return -1;
}
q = GetLinkList(L,x-1);
p = q->next;
q->next = p->next;
free(p);
p=NULL;
return 0;
}
5、单链表的定位(按序号以及按值)
linklist * GetLinkList(linklist * L,data_t pos)
{
linklist * q;
int i = 0;
q = L ;
if( L == NULL)
{
printf("Linklist is NULL !!!");
return NULL;
}
for(i=0;i<=pos;i++)
{
q = q->next;
}
return q;
}
6、单链表的排序
1、 排序的思想:
将链表头节点以及后续个节点先断开,然后使用排序算法一个一个比较后续节点数据的大小,一个一个的连接到头节点后面,直到最后一个节点,排序完毕。