您的位置:首页 > 理论基础 > 数据结构算法

线性表之单链表学习小结(初学数据结构必看)

2014-09-23 22:12 639 查看
花了好几个小时,详细规划出了整个过程,包括所有基本操作。。。有什么疑问请下方留言

#include<iostream>
using namespace std;

#define ElemType char
#define ERROR 0
#define OK 1
typedef struct Node
{
ElemType data;
struct Node *next;
}Node,*LinkList;

void init_linklist(LinkList L)/*对单链表进行初始化*/
{
L=(Node*)malloc(sizeof(Node)); /*申请结点空间*/
L->next=NULL;                      /*置为空表*/
}

void CreateFromHead(LinkList   L)
{
Node *s;
char 	c;
int 	flag=1,k=0;
while(flag)   /* flag初值为1,当输入"$"时,置flag为0,建表结束*/
{
c=getchar();
if(c!='$')
{
s=(LinkList)malloc(sizeof(Node)); /*建立新结点s*/
s->data=c;
s->next=L->next;/*将s结点插入表头*/
L->next=s;
if(k==0)
{k=1;s->next=NULL;}          //具体为啥不知道,但数据结构课程源程序的确是的结尾指向不为空,通过k标记,使得结尾为空
}
else
flag=0;
}
}

void CreateFromTail(LinkList L)
{
Node *r, *s;
char c;
int   flag =1; /*设置一个标志,初值为1,当输入"$"时,flag为0,建表结束*/
r=L;                /*r指针动态指向链表的当前表尾,以便于做尾插入,其初值指向头结点*/
while(flag)         /*循环输入表中元素值,将建立新结点s插入表尾*/
{
c=getchar();
if(c!='$')
{
s=(Node*)malloc(sizeof(Node));
s->data=c;
r->next=s;
r=s;
}
else
{
flag=0;
r->next=NULL;   /*将最后一个结点的next链域置为空,表示链表的结束*/
}
}
}
ElemType Get (LinkList  L, int i)
/*在带头结点的单链表L中查找第i个结点,若找到(1≤i≤n),则返回该结点的存储数值; */
{
int j;
Node  *p;
p=L;
j=0;   /*从头结点开始扫描*/
while ((p->next!=NULL)&&(j<i))
{
p=p->next;    /* 扫描下一结点*/
j++;   /* 已扫描结点计数器 */
}
if(i == j)
return p->data;   /* 找到了第i个结点 */
else
return NULL;   /* 找不到,i≤0或i>n */
}
int Locate( LinkList L,ElemType key)
/*在带头结点的单链表L中查找其结点值等于key的结点,若找到则返回该结点的位置p,否则返回NULL*/
{
Node *p;
int k=1;
p=L->next;    /*从表中第一个结点开始 */
while (p!=NULL)
{
if (p->data!=key)
p=p->next;
else
break; /*找到结点值=key时退出循环 */
k++;
}
return k;
}

int	ListLength(LinkList L)
/*求带头结点的单链表L的长度*/
{
Node *p;
int j;
p=L->next;
j=0;   /*用来存放单链表的长度*/
while(p!=NULL)
{
p=p->next;
j++;
}
return j;	/*j为求得的单链表长度*/
}

int InsList(LinkList L,int i,ElemType e)
/*在带头结点的单链表L中第i个位置插入值为e的新结点*/
{
Node *pre,*s;
int k;
if(i<=0)return ERROR;
pre=L;
k=0;                     /*从"头"开始,查找第i-1个结点*/
while(pre!=NULL&&k<i-1)  /*表未查完且未查到第i-1个时重复,找到pre指向第i-1个*/
{
pre=pre->next;
k=k+1;
}									/*查找第i-1结点*/
if(!pre)      /*如当前位置pre为空表已找完还未数到第i个,说明插入位置不合理*/
{
printf("插入位置不合理!");
return ERROR;
}
s=(Node*)malloc(sizeof(Node));   /*申请一个新的结点S */
s->data=e;                       /*值e置入s的数据域*/
s->next=pre->next;				/*修改指针,完成插入操作*/
pre->next=s;
return OK;
}
int DelList(LinkList L,int i,ElemType *e)
/*在带头结点的单链表L中删除第i个元素,并将删除的元素保存到变量*e中*/
{
Node *pre,*r;
int k;
pre=L;
k=0;
while(pre->next!=NULL && k<i-1)	/*寻找被删除结点i的前驱结点i-1使p指向它*/
{
pre=pre->next;
k=k+1;
}								/*查找第i-1个结点*/
if(!(pre->next))     /* 即while循环是因为p->next=NULL或i<1而跳出的,而是因为没有找到合法的前驱位置,说明删除位置i不合法。*/
{
printf("删除结点的位置i不合理!");
return ERROR;
}
r=pre->next;
pre->next=pre->next->next;    /*修改指针,删除结点r*/
*e = r->data;
free(r);    /*释放被删除的结点所占的内存空间*/
printf("成功删除结点!");
return OK;
}
LinkList MergeLinkList(LinkList LA, LinkList LB)
/*将递增有序的单链表LA和LB合并成一个递增有序的单链表LC*/
{
Node *pa,*pb;
Node *r;
LinkList LC;
/*将LC初始置空表。pa和pb分别指向两个单链表LA和LB中的第一个结点,r初值为LC*/
pa=LA->next;
pb=LB->next;
LC=LA;
LC->next=NULL;
r=LC;
/*当两个表中均未处理完时,比较选择将较小值结点插入到新表LC中。*/

while(pa!=NULL && pb!=NULL)
{
if(pa->data <= pb->data)
{
r->next=pa;
r=pa;
pa=pa->next;
}
else
{
r->next=pb;
r=pb;
pb=pb->next;
}
}
if(pa) /*若表LA未完,将表LA中后续元素链到新表LC表尾*/
r->next=pa;
else	 /*否则将表LB中后续元素链到新表LC表尾*/
r->next=pb;
//	free(LB);         原文是这么写的,不过释放失败,原因请看我的博客"浅析C语言malloc与free"

return(LC);
}
void print(LinkList L)
{
LinkList p=L->next;
int i=0;
while(p!=NULL)
{
cout<<p->data<<"  ";
p=p->next;
}
cout<<endl;
}
int main()
{
Node LA,LB;
LinkList LC;
int n;
ElemType key;
init_linklist(&LA);
init_linklist(&LB);

cout<<"以尾插法建立链表LB:(输入$结束)"<<endl;
CreateFromTail(&LA);
print(&LA);

cout<<"以头插法建立链表LB:(输入$结束)"<<endl;
CreateFromHead(&LB);
print(&LB);

cout<<"在LA中按序号查找某元素输出值"<<endl;
cin>>n;
cout<<Get (&LA,n)<<endl;

cout<<"在LA中按值查找某元素输出序号"<<endl;
cin>>key;
cout<<Locate(&LA,key)<<endl;

cout<<"求LA表的节点长度:"<<endl;
cout<<ListLength(&LA)<<endl;

cout<<"在LA表中插入数e(输入位置和e,注意此时的ElemType是char类型,最大支持读入9)"<<endl;
cin>>n;
cin>>key;
if(InsList(&LA,n,key))
{
cout<<"插入成功!"<<endl;
print(&LA);
}
else
cout<<"插入失败!"<<endl;

cout<<"在LA表中删除第i个元素(输入位置i)"<<endl;
cin>>n;
if(DelList(&LA,n,&key))
cout<<"删除的元素为:"<<key<<endl;
else
cout<<"删除失败!"<<endl;

cout<<"合并LA,LB后的链表为:"<<endl;
LC=MergeLinkList(&LA,&LB);
print(LC);
return 0;
}


附带:循环链表的合并算法

LinkList   merge_1(LinkList LA,LinkList LB)
{  /*此算法将两个采用头指针的循环单链表的首尾连接起来*/
Node *p, *q;
p=LA;
q=LB;
while (p->next!=LA)	p=p->next;	/*找到表LA的表尾,用p指向它*/
while (q->next!=LB)	q=q->next;	/*找到表LB的表尾,用q指向它*/
q->next=LA;	/*修改表LB 的尾指针,使之指向表LA 的头结点*/
p->next=LB->next; /*修改表LA的尾指针,使之指向表LB 中的第一个结点*/
free(LB);
return(LA);
}
LinkList  merge_2(LinkList RA,LinkList RB)
{  /*此算法将两个采用尾指针的循环链表首尾连接起来*/
Node *p;
p=RA->next; /*保存链表RA的头结点地址*/
RA->next=RB->next->next;/*链表RB的开始结点链到链表RA的终端结点之后*/
free(RB->next);/*释放链表RB的头结点*/
RB->next=p;/*链表RA的头结点链到链表RB的终端结点之后*/
return  RB;/*返回新循环链表的尾指针*/
}


双向链表的插入与删除

int DlinkIns(DoubleList L,int i,ElemType e)
{
DNode  *s,*p;
int k;
p=L;
k=0;                     /*从"头"开始,查找第i-1个结点*/
while(p->next!=L&&k<i)  /*表未查完且未查到第i-1个时重复,找到p指向第i个*/
{
p=p->next;
k=k+1;
}									/*查找第i-1结点*/
if(p->next == L)      /*如当前位置p为空表已找完还未数到第i个,说明插入位置不合理*/
{
printf("插入位置不合理!");
return ERROR;
}
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 OK;
}
else
return ERROR;
}
int	DlinkDel(DoubleList L,int i,ElemType *e)
{
DNode  *p;
int k;
p=L;
k=0;                     /*从"头"开始,查找第i个结点*/
while(p->next!=L && k<i)  /*表未查完且未查到第i个时重复,找到p指向第i个*/
{
p=p->next;
k=k+1;
}
if(p->next == L)
{
return ERROR;
}
else
{
*e=p->data;
p->prior->next=p->next;
p->next->prior=p->prior;
free(p);
return OK;
}
}


静态链表的初始化,节点分配&回收

void initial(StaticList space, int *av)
{
int k;
space[0].cursor=0;      /*设置已用静态单链表的头指针指向位置0*/
for(k=0;k<Maxsize-1;k++)
space[k].cursor=k+1;    /*连链*/
space[Maxsize-1].cursor=0;    /*标记链尾*/
*av=1;  /*设置备用链表头指针初值*/
}
int getnode(StaticList space, int *av)
/*从备用链表摘下一个结点空间,分配给待插入静态链表中的元素*/
{
int i;
i=*av;
*av=space[*av].cursor;
return i;
}
void   freenode(StaticList space, int *av, int k)
/*将下标为 k的空闲结点插入到备用链表*/
{
space[k].cursor=*av;
*av=k;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: