学习笔记2
##链表--循环链表
1、循环链表是一个首尾相接的链表。
特点:将单链表最后一个结点的指针域由 NULL 改为指向头结点或线性表中的第一个结点。
在表头插入或查找首元素,时间复杂性 O(1)
在表尾插入或查找尾元素,时间复杂性 O(n)
2、在单链表的每个结点里再增加一个指向其 前趋的指针域 prior。这样形成的链表中就有两条方向不同的链,我们称之为双 ( 向) 链表 。
双向链表的结点结构:
prior |data| next
初始化空循环单链表:
InitList(LinkList *L)
{
*L = (LinkList)malloc(sizeof(Node));
(*L)->next=NULL;
}
循环单链表查找示例:
Node *Locate( LinkList L, ElemType key )
{
Node *p; p=L->next; / * 从表中首元结点开始 * /
while (p!=L)
if (p->data!=key)
p=p->next;
else break; / * 找到结点key,退出循环 * /
return p;
}
单链表头插法示例:
void CreateFromHead( LinkList L)
{
Node *s; int flag=1;//标志--初值为1,当输入‘$’时,flag为0,建表结束
while(flag)
{
c=getchar();//接收一字符 if(c!= ‘$’) //如果字符不是‘$’,则执行头插
{
s=(Node *)malloc(sizeof(Node));
s->data=c;
s->next=L->next;
L->next=s;
}
else flag=0;
}
}
单链表尾插法示例
void CreateFromTail(LinkList L)
{
Node *r, *s; int flag=1;//标志--初值为1,当输入‘$’时, flag为0,建表结束
r=L;
while(flag)
{
c=getchar();//接收一字符
if(c!=’$’) //如果字符不是‘$’,则执行尾插
{
s=(Node *)malloc(sizeof(Node));
s->data=c;
r->next=s;
r=s;
}
else
{
flag=0;
r->next=L;
}
}
}
双向链表的结构定义:
typedef struct Dnode
{
ElemType data;
struct DNode *prior,*next;
} Dnode, * DoubleList;
双链表的插入操作示例:
int DlinkIns( DoubleList L, int i, ElemType e )
{
DNode *s,*p; //首先检查待插入的位置 i 是否合法,若位置 i 合法,则让指针 p 指向它
s=(DNode*)malloc(sizeof(DNode));
if (s)
{
s->data=e;
s->prior = p->prior;
p->prior->next = s;
s->next = p;
p->prior = s;
return TRUE;
}
else return FALSE;
}
双链表的删除操作示例:
int DlinkDel( DoubleList L, int i, ElemType *e )
{
DNode *p; //首先检查待插入的位置 i 是否合法,若位置 i 合法,则让指针 p 指向它
*e=p->data;
p->prior->next=p->next;
p->next->prior=p->prior;
free(p);
return TRUE;
}