结点
.结点个数n称为表长
, 当n=0时, 线性表不含有任何数据元素, 称为空表, 记为()线性表的顺序存储方法是: 将表中的结点依次存放在计算机内存中一组连续的存储单元中, 数据元素在线性表中的紧邻关系决定它们存储空间中的存储位置, 即逻辑结构中相邻的结点其存储位置也相邻.用顺序存储实现的线性表称为顺序表, 一般使用数据来表示顺序表.
一般情况下, 元素比较和移动的次数为: n-i+1
次, 如:顺序表有9个元素, 在第3个元素前插入一个新的元素,则需要移动的元素个数为: 9-3+1 =7个
分为: 单链表, 循环链表, 双向循环链表, 最简单的是单链表
data部分称为数据域,用于存储线性表的一个数据元素,
next部分称为指针或链域, 用于存放一个指针, 该指针指向本结点所含数据元素的直接后继结点.
所有结点通过指针链接形成链表(Link List),head称为头指针变量,该变量的值是指向单链表的第一个结点的指针.
LinkList InitiateLinkList() {
LinkList head; //头指针
head = malloc(sizeof(Node)); //动态构建一结点, 它是头结点
head->next=NULL; //该结点的指针域的值为NULL
return head;
}
int LengthLinkList(LinkList head){
Node * p = head; // 定义p为工作指针, 指向头结点
int cnt =0; //初始化计数器为0
while(p->next != NULL) { // 判断是否为尾结点
p = p->next; // 将指针移动到下一个结点
cnt++;
}
return cnt;
}
// 在单链表中, 查找第i个元素结点, 若找到, 则返回指向该指针结点的指针; 否则返回NULL
Node *GetLinklist(LinkList head, int i){
Node *p; // 定义一个工作指针
p=head->next //初始化指向头结点
int c = 1;
while((c<=i) && (p!=NULL)){
p=p->next;
c++;
}
if i==c return p;
else return NULL;
}
// 求表中第一个值等于x的结点的序号, 若不存在这种节点,返回结果为0
int LocateLinkList(LinkList head, DataType x){
Node *p;
p=head->next;
int c=0;
while(p!=NULL && p->data!=x){
i++;
p=p->next;
}
if (p!=NULL) return i+1;
else return 0;
}
void InsertLinklist(LinkList head, DataType x, int i){
Node *p, *q;
if (i==1) q=head;
else q = GetLinklist(head, i-1);
if (q==NULL) exit("找不到指定位置")
else {
p = malloc(sizeof(Node)); //生成新的结点
p->data = x; //新结点的数据域为x
p->next = q->next; // p结点next域指向q结点的指针域
q->next =p; //q结点的指针域指向p
}
}
void DeleteLinklist(LinkList head, int i){
Node *q, *p;
if (i==1) q=head;
else q = GetLinklist(head, i-1); // 先找到直接前驱结点
if (q!=NULL && q->next!=NULL){ // 若直接前驱结点存在且存待删结点存在
p=q->next; // 指向待删结点
q->next = p->next; //移出待删结点
free(p); // 释放已删除的节点空间
else exit("找不到结点")
}
}
在单链表中, 如果让最后一个结点的指针域指向第一个结点可以构成循环链表. 在循环链表中,从任一结点出发都能够扫描整个链表.
在单链表中, 每个结点中再设置一个指向其直接前驱的指针域(prior), 这样每个节点有两个指针
prior data next