单链表的基本操作有:
单链表的销毁,清空单链表,求单链表表长,判断链表是否为空,取值,查找,插入,删除,单链表的建立
1.单链表的定义:
typedef struct Lnode{
ElemType data;
struct Lnode *next;
}Lnode, *LinkList;
定义链表LinkList L;
定义结点指针LNode *p或者LinkList p;
2.用链式存储结构存储学生学号、姓名、成绩的方式:
第一种方式:
typedef Struct student{
char num[8];//数据域
char name[8];//数据域
int score;//数据域
struct student *next;//指针域
}Lnode, *LinkList;
第二种方式:
typedef Struct{
char num[8];//数据域
char name[8];//数据域
int score;//数据域
}ElemType;
typedef struct Lnode{
ElemType data;//数据域
struct Lnode *next;//指针域
}Lnode, *LinkList;
3.单链表的初始化
步骤:
1.生成新节点做头节点,用头指针L指向头节点。
2.将头结点的指针域置空。
Status InitList_L(LinkList &L){
L = new Lnode; //或L=(linkList) malloc (sizeof(LNode));
L->next = NULL;
return OK;
}
4.判断链表是否为空
int ListEmpty(LinkList L){ //若L为空表,则返回1,否则返回0
if(L->next)
return 0;
else
return 1;
}
5.单链表的销毁
(结束条件:L==NULL 循环条件L!=NULL或L)
Status DestroyList_L(LinkList &L){
Lnode *p;
while(L){
p=L;
L=L->next;
delete p;//或free(p)
}
return OK;
}
6.清空链表
链表存在,但是没有元素
反复执行
p=q; q=q->next;
结束条件:p==NULL 循环条件:p!=NULL
Status ClearList(LinkList &L){ //将L设置为空表
Lnode *p,*q;
p = L->next;
while(p) //没到表尾
{
q = p->next;
delete p;
p=q;
}
L->next = NULL;//头节点指针域为空
return OK;
}
7.求链表的表长
int ListLength_L(LinkList L)//返回L中数据元素的个数
{
Lnode* p;
p = L -> next;
int i = 0;
while(p)
{
i++;
p = p->next;
}
return i;
}
8.取值--取单链表第i个元素的内容
Status GetElem_L(LinkList L, int i, ElemType &e)
{
p = L -> next;
j = 1;
while(p&&j<i){
p=p->next;
j++;
}
if(!p||j>i) return ERROR;
e=p->data;
return OK;
}
9.查找
时间效率O(n)
①按值查找(返回地址)
Lnode *LocateElem_L(LinkList L, Elemtype e)
{
Lnode *p;
p = L->next;
while(p&&p->data!=e)
p=p->next;
return p;
}
②按值查找(返回序号)
Lnode *LocateElem_L(LinkList L, Elemtype e)
{
Lnode *p;
int j=0;
p = L->next;
while(p&&p->data!=e)
{
p=p->next;
j++;
}
return j;
}
10.插入元素
时间复杂度一般为O(1),但是实际操作中,要先查找到相应元素,所以时间复杂度为O(n)
Status ListInsert_L(LinkList &L, int i, ElemType e)
{
p = L;
j = 0;
while(p&&j<i-1)
{
p=p->next;
j++;
}
if(!p||j>i-1)return ERROR;
s = new Lnode;
s -> data = e;
s -> next = p -> next;
p -> next = s;
return OK;
}
11.删除结点
时间复杂度与插入相同。
关键一步是将待删除结点的前一个节点的next域先保存,然后将待删除结点的下一个结点的地址赋值给上上一个结点指针域。之后释放待删除结点的空间。
Status ListDelete_L(LinkList &L, int i, ElemType &e)
{
p = new Lnode;
q = new Lnode;
p = L;
j = 0;
while(p->next&&j<i-1)
{
p=p->next;
j++;
}
if(p->next||j>i-1)return ERROR;
q = p->next;
p->next = q->next;
e = q->data;
delete q;
return OK;
}
12.单链表的建立
①头插法
时间复杂度为O(n)
先插入最后一个元素,最后插入第一个元素。
void CreateList_H(LinkList &L, int n)
{
L= new Lnode;
L->next = NULL;
for(int i=0; i<n; i++)
{
p = new Lnode;
p->next = L->next;
L->next = p;
cin >> p->data;
}
}
②尾插法
通过尾指针操作
时间复杂度为O(n)
void CreateList_R(LinkList &L,int n)
{
L = new LNode;
L->next = NULL;
r = L; //其中,r为尾指针
for(int i=0; i<n; i++)
{
p = new Lnode;
cin >> p->data;
p->next = NULL;
r->next = p;
r = p;//指向新的尾结点
}
}