基本概念
其实不妨说这就是链表。其存储单元无须连续。
链表的组成单位为节点(Node)
首个节点称为头节点,最后一个节点称为尾节点。
我们一般直接使用Linklist L 来定义链表。使用LNode *p来定义一个节点指针
typedef struct LNode
{
ElemType data; //数据
struct LNode *next; //指向下一个节点
}LNode,*LinkList;
单链表基本操作的实现
说在前面
由于本人问题,仍然无法快速分清代码中“*p”等等,让人眼花缭乱。出于应试目的,所有的节点的创建统统使用LinkList p这样的样式来创建,避免了指针的来回转换。
以下的代码,均可以通过画图的方式来快速理解。但不便于用文字展示,所以请读者自行画图,敬请见谅!
单链表的初始化
Status initList(LinkList L){
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
return OK;
}
单链表的销毁
Status DestroyList(LinkList L){
LinkList p;
while((L)!=NULL){
p=L;
(L)=(L)->next;
free(p);
}
return OK;
}
单链表的清空
Status ClearList(LinkList L){
LinkList p,q;
p=L->next;
while(p==NULL){
q=p->next;
free(p);
p=q;
}
L->next=NULL;
return OK;
}
单链表的表长
int ListLenth(LinkList L){
LinkList p=L;
int count=0;
while(p!=NULL){
p=p->next;
count++;
}
return count;
}
取单链表的第i个元素
Status GetElem(LinkList L,int i,ElemType *e){
LinkList p=L->next;
int j=1;
while(p!=NULL&&j<i){
p=p->next;
j++;
}
if(p==NULL||j>i){
return ERROR;
}
e=p->data;
return OK;
}
单链表按值查找
查找时要从头开始所以复杂度 O(n)
//返回数据的位置
LinkList LocalElem(LinkList L,ElemType e){
LinkList p=L->next;
while(p!=NULL&&p->data!=e){
p=p->next;
}
return p;
}
//返回数据的位置序号
int LocalElem2(LinkList L,ElemType e){
LinkList p=L->next;
int j=1;
while(p->data!=e&&p!=NULL){
p=p->next;
j++;
}
if(p==NULL){
return 0;
}else {
return j;
}
}
在第i个节点插入e
需要从头查找,复杂度O(n)
Status ListInsert(LinkList L,int i,ElemType e){
LinkList p=L;
int j=0;
while (p!=NULL&&j<i-1)//寻找第i-1个节点,使得要插入节点与其链接
{
p=p->next;
j++;
}
if(p==NULL||j>i-1){ //i不合法
return ERROR;
}
LinkList s=(LinkList)malloc(sizeof(LNode));
s->data=e;
s->next=p->next;
p->next=s;
return OK;
}
删除第i个节点
需要从头查找 复杂度O(n)
Status ListDelete(LinkList L,int i,ElemType *e){
LinkList p=L;
int j=0;
while(p->next!=NULL&&j<i-1){ //到达要删除节点的前一个
p=p->next;
j++;
}
if(p->next==NULL||j>i-1){
return ERROR;
}
LinkList q=p->next;
p->next=p->next->next;
e=q->data;
free(q);
return OK;
}
头插法创建单链表
复杂度为O(n)
void CreateList_H(LinkList L,int n){
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
for(int i=0;i<n;i++){
LinkList p=(LinkList)malloc(sizeof(LNode));
scanf(&p->data);
p->next=L->next; //把头节点后面的一串接到p的next上
L->next=p; //连接到头节点
}
}
尾插法创建单链表
复杂度为O(n)
void CreateList_R(LinkList L,int n){
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
LinkList r=L;
for(int i=0;i<n;i++){
LinkList p=(LinkList)malloc(sizeof(LNode));
p->next=NULL;
scanf(&p->data);
r->next=p; //插入到表尾
r=p; //更新最新的表尾
}
}