描述
单链表是一种基本的线性数据结构,它由一系列节点组成,每个节点包含数据元素和一个指向下一个节点的引用(指针)。链表的特点是元素的存储位置不是连续的,而是通过节点中的指针来建立元素之间的逻辑关系。
特点
- 非连续存储: 单链表中的元素存储在不同的内存块中,通过节点的指针将它们连接在一起,而不像顺序表那样是连续存储的。
- 节点结构: 每个节点包含两部分信息,即数据元素和指向下一个节点的指针。最后一个节点的指针通常指向空(NULL),表示链表的结束。
- 动态大小: 单链表的大小可以动态地增长或缩小,因为每次插入或删除操作只需要修改指针,而不需要重新分配内存。
操作
- 插入操作: 在链表中插入一个新元素通常包括三个步骤:创建新节点,调整指针使其指向正确的位置,然后更新前一个节点的指针。
- 删除操作: 删除一个节点需要调整前一个节点的指针,将其指向被删除节点的下一个节点,并释放被删除节点的内存。
- 查找操作: 由于单链表的存储结构,查找操作需要从头节点开始逐个遍历,直到找到目标元素或达到链表末尾。这导致链表在查找上的效率相对较低。
- 反转操作: 反转链表是一种常见的操作,可以通过修改节点之间的指针来实现。
代码实现
1.头插法
//头插法建立单链表
LinkList List_HeadInsert(LinkList &L){
LNode *s;
int x;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
scanf("%d",&x);
while(x!=8888){
s->data=x;
s->next=L->next;
L->next=s;
scanf("%d",&x);
}
return L;
}
2.尾插法
//尾插法建立单链表
LinkList List_TailInsert(LinkList &L){
int x;
L=(LinkList)malloc(sizeof(LNode));//初始化表,建立头节点
LNode *s,*r=L;//r为表尾指针
scanf("%d",&x);
while(x!=8888){
s=(LNode *)malloc(sizeof(LNode));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return L;
}
3.完整代码
#include<stdio.h>
#include<stdlib.h>
//带头结点的单链表
typedef struct LNode{
int data;
struct LNode *next;
} LNode,*LinkList;
//初始化单链表
bool InitList(LinkList &L){
L=(LNode *)malloc(sizeof(LNode));//头节点
if(L==NULL){
return false;
}
L->next=NULL;//头节点之后没有任何节点
return true;
}
//按位插入(带头节点)
bool ListInsert(LinkList &L,int i,int e){
if(i<1){
return false;
}
LNode *p;//指向当前节点
int j=0;//p指向哪一个节点
p=L;//指向头节点
while(p!=NULL&&j<i-1){
p=p->next;
j++;
}//到达需要插入指定位置的前一个节点
if(p==NULL)
return false;
LNode *s=(LNode *)malloc(sizeof(LNode));
s->data=e;
s->next=p->next;
p->next=s;
return true;//插入成功
}
//指定节点的后插操作
bool InsertNextNode(LNode *p,int e){
if(p==NULL)
return false;
LNode *s=(LNode*)malloc(sizeof(LNode));
if(s==NULL)
return false;//内存不足,分配失败
s->data=e;
s->next=p->next;
p->next=s;
return true;
}
//指定节点的前插操作
bool InsertPriorNode(LNode *p,int e){
if(p==NULL)
return false;
LNode *s=(LNode*)malloc(sizeof(LNode));
if(s==NULL)
return false;//内存不足,分配失败
s->data=p->data;
s->next=p->next;
p->next=s;
p->data=e;
return true;
}
//按位序删除(带头节点)
bool ListDelete(LinkList &L,int i,int &e){
if(i<1)
return false;
LNode *p;
int j=0;
p=L;
while(p!=NULL&&j<i-1){
p=p->next;
j++;
}
//到达i-1位置节点
if(p==NULL)
return false;
if(p->next==NULL)//第i个节点为空
return false;
LNode *s=p->next;
e=s->data;
p->next=s->next;
free(s);
return true;
}
//按位查找
LNode *GetElem(LinkList L,int i){
if(i<0)
return NULL;
LNode *p;
int j=0;
p=L;
while(p!=NULL &&j<i){
p=p->next;
j++;
}
return p;
}
//按值查找
LNode *LocateElem(LinkList L,int e){
LNode*p=L->next;//从第一个节点开始找
while(p!=NULL &&p->data!=e){
p=p->next;
}
return p;
}
//求链表的长度
int Length(LinkList L){
int len=0;
LNode*p=L;
while(p->next!=NULL){
len++;
}
return len;
}
//尾插法建立单链表
LinkList List_TailInsert(LinkList &L){
int x;
L=(LinkList)malloc(sizeof(LNode));//初始化表,建立头节点
LNode *s,*r=L;//r为表尾指针
scanf("%d",&x);
while(x!=8888){
s=(LNode *)malloc(sizeof(LNode));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return L;
}
//头插法建立单链表
LinkList List_HeadInsert(LinkList &L){
LNode *s;
int x;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
scanf("%d",&x);
while(x!=8888){
s->data=x;
s->next=L->next;
L->next=s;
scanf("%d",&x);
}
return L;
}
int main(){
}