定义
n个节点链结成一个链表,即为线性表的链式存储结构,因为此链表中的每个结点中只包含一个指针域,所以叫单链表。
头指针与头结点
头指针:
a.指向第一个结点的指针,若有头结点,则指向头结点
b.头指针带有标识作用,常以头指针冠以链表的名字
c.无论链表是否为空,头指针均不为空。是链表的必要元素
头结点:
a.为了操作统一和方便而设立,放在第一个元素的结点之前,其数据域一般无意义(可存放链表的长度)
b.方便插入删除操作的统一性
c.不是链表的必要元素
C定义
typedef struct Node{
ElemType data;
struct Node *next;
}Node;
typedef struct Node *LinkList;
查询元素
#define OK 1
#define ERROR 0
int getLinkListElem(LinkList L, int i, ElemType *e)
{
int j = 1;
LinkList p;
p = L->next;
while (p && j < i) {
p = p->next;
++j;
}
if (!p || j > i) {
return ERROR;
}
*e = p->data;
return OK;
}
遍历操作导致时间复杂度为O(n)
插入数据
int linkListInsert(LinkList *L, int i, ElemType e)
{
int j = 1;
LinkList p,r;
p = *L;
while (p && j < i) {
p = p->next;
++j;
}
if (!p || j > i) {
return ERROR;
}
r = (LinkList)malloc(sizeof(Node));
r->data = e;
r->next = p->next;
p->next = r;
return OK;
}
删除数据
int linkListDelete(LinkList *L, int i)
{
int j = 1;
LinkList p, q;
p = *L;
while (p && j < i) {
p = p->next;
++j;
}
if (!p || j > i) {
return ERROR;
}
q = p->next;
p->next = q->next;
free(q);
return OK;
}
整表创建——头插法
void createListHead(LinkList *L, int n)
{
*L = (LinkList)malloc(sizeof(Node));
(*L)->next = NULL;
int i;
LinkList p;
srand(time(0));
for (i = 0; i < n; i++) {
p = (LinkList)malloc(sizeof(Node));
p->data = rand()%100 + 1;
p->next = (*L)->next;
(*L)->next = p;
}
}
整表创建——尾插法
void createListTail(LinkList *L, int n)
{
*L = (LinkList)malloc(sizeof(Node));
LinkList p,q;
p = *L;
int i;
srand(time(0));
for (i = 0; i < n; i ++) {
q = (LinkList)malloc(sizeof(Node));
q->data = rand()%100 + 1;
q->next = p->next;
p->next = q;
p = q;
}
}
整表删除
int clearList(LinkList *L)
{
LinkList p,q;
p = (*L)->next;
while (p) {
q = p->next;
free(p);
p = q;
}
(*L)->next = NULL;
return OK;
}