首页 > 学院 > 开发设计 > 正文

线性表之双链表基本操作

2019-11-14 08:43:47
字体:
来源:转载
供稿:网友
/* *姓名:刘金石 *时间2017年2月5日 *线性表之双链表基本操作 */#include <stdio.h>#include <stdlib.h>//双链表的存储结构typedef char ElemType;typedef struct DNode{    ElemType date;//存放元素值    struct DNode *PRior;//指向前驱节点    struct DNode *next;//指向后继节点}DLinkList;//头插法建立双链表void InitList(DLinkList *&L)	//初始化{	L=(DLinkList *)malloc(sizeof(DLinkList));  	//创建头结点	L->prior=L->next=NULL;}void DestroyList(DLinkList *&L)	//销毁线性表{	DLinkList *p=L,*q=p->next;	while (q!=NULL)	{		free(p);		p=q;		q=p->next;	}	free(p);}bool ListEmpty(DLinkList *L)	//判线性表是否为空表{	return(L->next==NULL);}int ListLength(DLinkList *L)	//求线性表的长度{	DLinkList *p=L;int i=0;	while (p->next!=NULL)	{		i++;		p=p->next;	}	return(i);}void DispList(DLinkList *L)	//输出线性表{	DLinkList *p=L->next;	while (p!=NULL)	{		printf("%c ",p->date);		p=p->next;	}	printf("/n");}bool GetElem(DLinkList *L,int i,ElemType &e)	//求线性表中某个数据元素值{	int j=0;	DLinkList *p=L;	while (j<i && p!=NULL)	{		j++;		p=p->next;	}	if (p==NULL)		return false;	else	{		e=p->date;		return true;	}}int LocateElem(DLinkList *&L,ElemType e)	//按元素值查找{	int n=1;	DLinkList *p=L->next;	while (p!=NULL && p->date!=e)	{		n++;		p=p->next;	}	if (p==NULL)		return(0);	else		return(n);}void CreateListF(DLinkList *&L,ElemType a[],int n){    DLinkList *s;    int i=0;    L=(DLinkList *)malloc(sizeof(DLinkList));    L->next=L->prior=NULL;//前后指针域置为NULL    for(i=0;i<n;i++)    {        s=(DLinkList *)malloc(sizeof(DLinkList));        s->date=a[i];        /*************************/        s->next=L->next;        if(L->next!=NULL)//若L后存在数据节点,则修改L->next的前驱指针            L->next->prior=s;        L->next=s;        s->prior=L;        /*************************/    }}//尾插法建立双链表void CreateListR(DLinkList *&L,ElemType a[],int n){    DLinkList *s,*r;//r指针指向链表的最后一个节点    int i=0;    L=(DLinkList *)malloc(sizeof(DLinkList));    r=L;    for(i=0;i<n;i++)    {        s=(DLinkList *)malloc(sizeof(DLinkList));        s->date=a[i];        /*************************/        L->next=s;        s->prior=L;        r=s;//r指向尾节点        /*************************/    }    r->next=NULL;}//插入节点bool ListInsert(DLinkList *&L,int i,ElemType e){//次算法在双莲表第i个位置插入值为e的节点    int j=0;    DLinkList *p=L,*s;    /*************************/    //找到第i-1个节点    while(j<i-1&&p!=NULL)    {        j++;        p=p->next;    }    /*************************/    if(p==NULL)        return false;    else    {        s=(DLinkList *)malloc(sizeof(DLinkList));        s->date=e;        /*************************/        //头插法        s->next=p->next;        if(p->next!=NULL)            p->next->prior=s;        s->prior=p;        p->next=s;        /*************************/        return true;    }}//删除双莲表中第i个节点bool ListDelete(DLinkList *&L,int i,ElemType &e){    int j=0;    DLinkList *p=L,*q;    /*************************/    //找到第i-1个节点    while(j<i-1&&p!=NULL)    {        j++;        p=p->next;    }    /*************************/    if(p==NULL)        return false;    else    {        q=p->next;        if(q==NULL)            return false;        e=q->date;        /*************************/        p->next=q->next;        if(p->next!=NULL)//若*p后存在后继节点则修改其前驱指针           p->next->prior=p;        free(q);//释放*q节点        /*************************/        return true;    }}int main(){	DLinkList *h;	ElemType e;	printf("双链表的基本运算如下:/n");	printf("  (1)初始化双链表h/n");	InitList(h);	printf("  (2)依次采用尾插法插入a,b,c,d,e元素/n");	ListInsert(h,1,'a');	ListInsert(h,2,'b');	ListInsert(h,3,'c');	ListInsert(h,4,'d');	ListInsert(h,5,'e');	printf("  (3)输出双链表h:");	DispList(h);	printf("  (4)双链表h长度=%d/n",ListLength(h));	printf("  (5)双链表h为%s/n",(ListEmpty(h)?"空":"非空"));	GetElem(h,3,e);	printf("  (6)双链表h的第3个元素=%c/n",e);	printf("  (7)元素a的位置=%d/n",LocateElem(h,'a'));	printf("  (8)在第4个元素位置上插入f元素/n");	ListInsert(h,4,'f');	printf("  (9)输出双链表h:");	DispList(h);	printf("  (10)删除h的第3个元素/n");	ListDelete(h,3,e);	printf("  (11)输出双链表h:");	DispList(h);	printf("  (12)释放双链表h/n");	DestroyList(h);	return 0;}运行结果:
总结:双链表的基本操作和单链表差不太多,就是多了一个指针。有时候不清楚可以画一下图,思路就清晰了。像插入元素删除元素定位元素等操作都是先找到元素或者前一个元素的位置,此过程用while循环,然后就是前插或者后插法的运用。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表