单链表
数据类型定义
typedef struct LNode{
ElemType data; //数据域
struct LNode *next; //指针域
}LNode,*LinkList;
LinkList L; //L为单链表的头指针
注: LNode*和LinkList类型实际是一样的
基本操作
取值操作
status GetELem_L(LinkList L,int i,ElemType &e){
//L为带头结点的单链表的头指针,当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR
p = L->next; //p指向首元结点
j=1; //j为计数器
while(p && j < i){
p = p->next;
++j;
} //沿指针向后查找,直至第i个元素或 到表尾
if(!p || j > i)
return OK; //第i个元素不存在
e = p->data;
return OK;
}//GetELem_L
时间复杂度: O(n)
查找操作
LNode LocateElem_L(LinkList L,ElemType e){
//从单链表头节点开始查找第一个数据域等于e的结点
LNode *p=L->next;
while(p != NULL && p->data != e)
p = p->next; //从第一个结点开始查找数据域为e的结点
return p; //找到后返回该结点指针,否则返回NULL
}//LocateElem_L
时间复杂度: O(n)
插入操作
status ListInsert_L(LinkList &L,int i,ElemType e){
//在带头结点的单链表L中第i个位置之前插入元素e
p = L;
j = 0;
while(p && j < i-1){
p = p->next;
j++;
} //顺指针找到第i- 1个结点
if(!p || j > i-1)
return ERROR; //i小于1或i大于表长加一
s = (LinkList)malloc(sizeof(LNode)); //生成新结点
s->data = e;
s->next = p->next;
p->next = s; //插入L中
return OK;
}//ListInsert_L
时间复杂度: O(n)
删除操作
statues ListDelete_L(LinkList &L,int i,ElemType &e){
//在带头结点的单链表L中删除第i个元素,并用e返回其值
p = L;
j = 0;
while(p->next && j < i-1){
p = p->next;
j++;
} //顺指针找到第i-1个结点
if(!(p->next) || j > i-1)
return ERROR; //i小于1或者i大于表长
q = p->next; //q指向第i个结点
p->next = q->next;
e = q->data; //取值
free(q); //释放所删结点的空间
return OK;
}//ListDelete_L
时间复杂度: O(n)
单链表存储实现总结
- 用一组地址任意的存储单元,不需要预分配空间,空间不会闲置或溢出
- 逻辑上相邻的元素物理上不一定相邻,即物理次序和逻辑次序不一定一致
- 除了存放元素值,还要存放表示元素之间关系的指针,存储密度<1
- 不支持随机访问(又称直接访问)
- 插入元素不需要移动大量元素
- 适合表长变化大,经常插入删除的场合