Fork me on GitHub

03 线性表的链式存储

线性表的链式存储

一、线性表的链式结构分类

1.建立单链表

引用的用处实际上就是使传入变量的本身可以被修改。

①传入引用型指针变量L , 数组a, 长度n
②定义一个指向结构体的指针变量s。
③初始化空链表L;
④循环:
1.为指针s分配新的结点,并赋予数组的对应值,
2.将s插入至头结点之后。
s->next = L->next;
L->next = s;

尾插法
①传入引用型指针变量L , 数组a, 长度n
②定义两个指向结构体的指针变量s,r。
③初始化空链表L;
④令r = L,等价于尾结点。
④循环:
1.为指针s分配新的结点,并赋予数组的对应值;
2.将s插入在尾结点r之后;
3.令r = s,重新成为尾结点。
⑤ r->next = NULL;

/*头插法*/
void CreateListF(LinkNode *&L, ElemType a[], int n){
    LinkNode *s;
    L = (LinkNode *)malloc(sizeof(LinkNode));
    L->next = NULL;
    for(int i = 0; i < n; i++){
        s = (LinkNode *)malloc(sizeof(LinkNode));
        s->data = a[i];
        s->next = L->next;
        L->next = s;
    }
}

/*尾插法*/
void CreateListR(LinkNode *&L, ElemType a[], int n){
    LinkNode *s,*r;
    L = (LinkNode *)malloc(sizeof(LinkNode));
    L->next = NULL;
    r = L;
    for(int i = 0; i < n; i++){
        s = (LinkNode *)malloc(sizeof(LinkNode));
        s->data = a[i];
        r->next = s;
        r = s;
    }
    r->next = NULL;
}

2.初始化链表

void InitList(ListNode *&L){
    L = (LinkNode *)malloc(sizeof(LinkNode));
    L->next = NULL;
}

3.销毁链表

①传入引用型指针变量L
②定义指向结构体的指针pre,并使其指向L;定义指向结构体的指针p,使其指向pre->next;
③循环:只要p!=NULL
1.释放p的前一个结点pre;
2.pre=p;
p=pre->next;
④释放最后一个.pre

void DestroyList(LinkNode *&L){
    LinkNode *pre = L, *P = pre->next;
    while(P != NULL){
        free(pre);
        pre = p;
        p = pre->next;
    }
    free(pre);
}

4.是否为空

bool ListEmpty(LinkNode *L)
{
	return(L->next==NULL);//判断下一个指向的结构体指针是否为空
}

5.返回长度

①传入结构体指针L
②定义指向L的结构体指针p
③循环遍历p->next != NULL,i++
④返回 i

int ListLength(LinkNode *L)
{
	LinkNode *p=L;
    int i=0;
	while (p->next!=NULL)/
	{	
        i++;
        p = p->next;
	}
	return i;//比实际结点数少1,因为有空头结点
}

6.输出单链表

void DispList(LinkNode *L)
{
	LinkNode *p = L->next;
	while (p!=NULL)
	{	printf("%d ",p->data);
		p = p->next;
	}
	printf("\n");
}

7.获取第i个元素值

bool GetElem(LinkNode *L, int i, ElemType &e){
    int j = 0;
    LinkNode *p =L;
    if(i<=0)
        return false;
    while(j < i && p != NULL){
        j++;
        p = p->next;
    }
    if(p == NULL)
        return false;
    else{
        e = p->data;
        return true;
    }
}

8.确认某个元素的位置

int LocateElem(LinkNode *L,ElemType e)
{
	LinkNode *p=L->next;
	int n = 1;
	while (p!=NULL && p->data!=e)
	{	p = p->next;
		n++;
	}
	if (p==NULL)
		return 0;
	else
		return n;
}

9.第i个位置插入元素

①判断 i
②查到第 i-1个 结点p
③插入至 p 后

bool ListInsert(LinkNode *&L,int i,ElemType e)
{
	int j = 0;
	LinkNode *p = L,*s;
	if(i<=0) 
        return false;			//i错误返回假
	while(j<i-1 && p!=NULL)		//查找第i-1个结点p
	{	
         j++;
		p=p->next;
	}
	if (p == NULL)					//未找到位序为i-1的结点
		return false;
	else							//找到位序为i-1的结点*p
	{	
         s=(LinkNode *)malloc(sizeof(LinkNode));//创建新结点*s
		s->data = e;
		s->next = p->next;			//将s结点插入到结点p之后
		p->next = s;
		return true;
	}
}

10.删除第i个元素

bool ListDelete(LinkNode *&L,int i,ElemType &e)
{
	int j = 0;
	LinkNode *p = L,*q;
	if (i <= 0) 
        return false;		//i错误返回假
	while (j < i-1 && p!=NULL)	//查找第i-1个结点
	{	
         j++;
		p=p->next;
	}
	if (p == NULL)				//未找到位序为i-1的结点
		return false;
	else						//找到位序为i-1的结点p
	{	
         q = p->next;				//q指向要删除的结点
		if(q==NULL) 
			return false;		//若不存在第i个结点,返回false
		e = q->data;
		p->next = q->next;		//从单链表中删除q结点
		free(q);				//释放q结点
		return true;
	}
}
  1. 全部代码

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#define MaxSize 50
typedef int ElemType;
typedef struct LNode  
{
	ElemType data;
	struct LNode *next;		//指向后继结点
} LinkNode;		
void CreateListF(LinkNode *&L,ElemType a[],int n);
void CreateListR(LinkNode *&L,ElemType a[],int n);
void InitList(LinkNode *&L);
void DestroyList(LinkNode *&L);
bool ListEmpty(LinkNode *L);
int ListLength(LinkNode *L);
void DispList(LinkNode *L);
bool GetElem(LinkNode *L, int i, ElemType &e);
int LocateElem(LinkNode *L, ElemType e);
bool ListInsert(LinkNode *&L,int i,ElemType e);
bool ListDelete(LinkNode *&L,int i);

void CreateListF(LinkNode *&L,ElemType a[],int n)
//头插法建立单链表
{
	LinkNode *s;
	L=(LinkNode *)malloc(sizeof(LinkNode));  	//创建头结点
	L->next=NULL;
	for (int i=0;i<n;i++)
	{	
		s=(LinkNode *)malloc(sizeof(LinkNode));//创建新结点s
		s->data=a[i];
		s->next=L->next;			//将结点s插在原开始结点之前,头结点之后
		L->next=s;
	}
}
void CreateListR(LinkNode *&L,ElemType a[],int n)
//尾插法建立单链表
{
	LinkNode *s,*r;
	L=(LinkNode *)malloc(sizeof(LinkNode));  	//创建头结点
	L->next=NULL;
	r=L;					//r始终指向终端结点,开始时指向头结点
	for (int i=0;i<n;i++)
	{	
		s=(LinkNode *)malloc(sizeof(LinkNode));//创建新结点s
		s->data=a[i];
		r->next=s;			//将结点s插入结点r之后
		r=s;
	}
	r->next=NULL;			//终端结点next域置为NULL
}
void InitList(LinkNode *&L)
{
	L=(LinkNode *)malloc(sizeof(LinkNode));  	//创建头结点
	L->next=NULL;
}
void DestroyList(LinkNode *&L)
{
	LinkNode *pre=L,*p=pre->next;
	while (p!=NULL)
	{	free(pre);
		pre=p;
		p=pre->next;
	}
	free(pre);	//此时p为NULL,pre指向尾结点,释放它
}
bool ListEmpty(LinkNode *L)
{
	return(L->next==NULL);
}
int ListLength(LinkNode *L)
{
	LinkNode *p=L;int i=0;
	while (p->next!=NULL)
	{	i++;
		p=p->next;
	}
	return(i);
}
void DispList(LinkNode *L)
{
	LinkNode *p=L->next;
	while (p!=NULL)
	{	printf("%d ",p->data);
		p=p->next;
	}
	printf("\n");
}
bool GetElem(LinkNode *L,int i,ElemType &e)
{
	int j=0;
	LinkNode *p=L;
	if (i<=0) return false;		//i错误返回假
	while (j<i && p!=NULL)
	{	j++;
		p=p->next;
	}
	if (p==NULL)				//不存在第i个数据结点
		return false;
	else						//存在第i个数据结点
	{	e=p->data;
		return true;
	}
}
int LocateElem(LinkNode *L,ElemType e)
{
	LinkNode *p=L->next;
	int n=1;
	while (p!=NULL && p->data!=e)
	{	p=p->next;
		n++;
	}
	if (p==NULL)
		return(0);
	else
		return(n);
}
bool ListInsert(LinkNode *&L,int i,ElemType e)
{
	int j=0;
	LinkNode *p=L,*s;
	if (i<=0) return false;			//i错误返回假
	while (j<i-1 && p!=NULL)		//查找第i-1个结点p
	{	j++;
		p=p->next;
	}
	if (p==NULL)					//未找到位序为i-1的结点
		return false;
	else							//找到位序为i-1的结点*p
	{	s=(LinkNode *)malloc(sizeof(LinkNode));//创建新结点*s
		s->data=e;
		s->next=p->next;			//将s结点插入到结点p之后
		p->next=s;
		return true;
	}
}
bool ListDelete(LinkNode *&L,int i,ElemType &e)
{
	int j=0;
	LinkNode *p=L,*q;
	if (i<=0) return false;		//i错误返回假
	while (j<i-1 && p!=NULL)	//查找第i-1个结点
	{	j++;
		p=p->next;
	}
	if (p==NULL)				//未找到位序为i-1的结点
		return false;
	else						//找到位序为i-1的结点p
	{	q=p->next;				//q指向要删除的结点
		if (q==NULL) 
			return false;		//若不存在第i个结点,返回false
		e=q->data;
		p->next=q->next;		//从单链表中删除q结点
		free(q);				//释放q结点
		return true;
	}
}

int main()
{
    LinkNode *lk;
    ElemType a[6]= {5,8,7,2,4,9};
    ElemType e;
    int i,x,choice;
    printf("第一步.创建单链表......\n");
    CreateListF(lk, a, 6);
    while(1){
    	printf("创建成功!请选择菜单执行相关操作\n");
	    printf("		1.销毁单链表\n");
	    printf("		2.判定单链表是否为空\n");
	    printf("		3.求单链表的长度\n");
	    printf("		4.输出单链表\n");
	    printf("		5.求单链表第i个位置上的元素\n");
	    printf("		6.查找单链表中元素e的位置\n");
	    printf("		7.在单链表第i个位置插入元素\n");
	    printf("		8.删除单链表第i个位置上的元素\n");
	    printf("		0.退出\n");
	    printf("		请输入你的选择:");
	    scanf("%d",&choice);
		switch(choice)
		{
			case 0: exit(0); 
			case 1: DestroyList(lk);
					printf("单链表销毁成功~~程序直接退出!!");
					exit(0);
			case 2: if(ListEmpty(lk))
						printf("单链表为空!");
					else
						printf("单链表不为空!");
					break;
			case 3: printf("该单链表长度为%d\n",ListLength(lk));
					break;
			case 4: printf("输出单链表:\n");
					DispList(lk);
					break;
			case 5: printf("请输入待查找元素的位置:");
					scanf("%d",&i);
					GetElem(lk, i, e);
					printf("第%d个位置上的元素为%d",i,e);
					break;
			case 6: printf("请输入要查找的元素:");
					scanf("%d",&x);
					printf("%d元素在单链表的第%d个位置\n",x,LocateElem(lk,x));
					break;
			case 7: printf("请输入要插入位置和值(空格隔开):");
					scanf("%d%d",&i,&x);
					ListInsert(lk,i,x);
					break;
			case 8: printf("请输入要删除的位置");
					scanf("%d",&i);
					ListDelete(lk, i, e);
					break;
		}
		printf("按任意键继续……");
		getchar();getchar();
    }
    return 0;
}

2.循环链表 CLinkNode

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h> 
typedef int ElemType;
typedef struct LNode
{
	ElemType data;
    struct LNode *next;
} LinkNode;
//头插法建立循环单链表
void CreateListF(LinkNode *&L,ElemType a[],int n)
{
	LinkNode *s;
    int i;
	L=(LinkNode *)malloc(sizeof(LinkNode));
	L->next=NULL;
	for (i=0;i<n;i++)
	{	
		s=(LinkNode *)malloc(sizeof(LinkNode));
		s->data=a[i];
		s->next=L->next;
		L->next=s;
	}
    /*令尾结点next指向头结点*/
	s=L->next;	
	while (s->next!=NULL)//查找尾结点,由s指向它
		s=s->next;
	s->next=L;//尾结点next域指向头结点

}
void CreateListR(LinkNode *&L,ElemType a[],int n)
//尾插法建立循环单链表
{
	LinkNode *s,*r;
    int i;
	L=(LinkNode *)malloc(sizeof(LinkNode));
	L->next=NULL;
	r=L;//r始终指向终端结点,开始时指向头结点
	for (i=0;i<n;i++)
	{	
		s=(LinkNode *)malloc(sizeof(LinkNode));
		s->data=a[i];
		r->next=s;
		r=s;
	}
	r->next=L;//尾结点next域指向头结点
}
void InitList(LinkNode *&L)
{
	L=(LinkNode *)malloc(sizeof(LinkNode));	//创建头结点
	L->next=L;
}
void DestroyList(LinkNode *&L)
{
	LinkNode *p=L,*q=p->next;
	while (q!=L)
	{
		free(p);
		p=q;
		q=p->next;
	}
	free(p);
}
bool ListEmpty(LinkNode *L)
{
	return(L->next==L);
}
int ListLength(LinkNode *L)
{
	LinkNode *p=L;
    int i=0;
	while (p->next!=L)
	{
		i++;
		p=p->next;
	}
	return(i);
}
void DispList(LinkNode *L)
{
	LinkNode *p=L->next;
	while (p!=L)
	{
		printf("%d ",p->data);
		p=p->next;
	}
	printf("\n");
}
bool GetElem(LinkNode *L,int i,ElemType &e)
{
	int j=0;
	LinkNode *p;
	if (L->next!=L)//单链表不为空表时
	{
		if(i==1)
		{
			e=L->next->data;
			return true;
		}
		else//i不为1时
		{
			p=L->next;
			while (j<i-1 && p!=L)//j==i-1或者p==L时退出循环
			{
				j++;
				p=p->next;
			}
			if (p==L)
				return false;
			else
			{
				e=p->data;
				return true;
			}
		}
	}
	else//单链表为空表时
		return false;
}
int LocateElem(LinkNode *L,ElemType e)
{
	LinkNode *p=L->next;
	int n=1;
	while (p!=L && p->data!=e)
	{
		p=p->next;
		n++;
	}
	if (p==L)
		return(0);
	else
		return(n);
}
bool ListInsert(LinkNode *&L,int i,ElemType e)
{
	int j=0;
	LinkNode *p = L, *s;
	if(p->next == L || i == 1)//原单链表为空表或i==1时
	{
		s = (LinkNode *)malloc(sizeof(LinkNode));//创建新结点s
		s->data = e;								
		s->next = p->next;//将结点s插入到结点p之后
		p->next = s;
		return true;
	}
	else
	{
		p=L->next;
		while (j<i-2 && p!=L)//第i-1个结点的序标为i-2 
		{
			j++;
			p=p->next;
		}
		if (p==L)//未找到第i-1个结点
			return false;
		else//找到第i-1个结点p
		{
			s=(LinkNode *)malloc(sizeof(LinkNode));	//创建新结点s
			s->data=e;								
			s->next=p->next;//将结点s插入到结点p之后
			p->next=s;
			return true;
		}
	}
}
bool ListDelete(LinkNode *&L,int i,ElemType &e)
{
	int j=0;
	LinkNode *p=L,*q;
	if(p->next!=L)//原单链表不为空表时
	{
		if(i==1)//i==1时
		{
			q=L->next;//删除第1个结点
			e=q->data;
			L->next=q->next;
			free(q);
			return true;
		}
		else//i不为1时
		{
			p=L->next;
			while (j<i-2 && p!=L)//第i-1个结点的序标为i-2 
			{
				j++;
				p=p->next;
			}
			if(p==L)//未找到第i-1个结点
				return false;
			else//找到第i-1个结点p
			{
				q=p->next;//q指向要删除的结点
				e=q->data;
				p->next=q->next;//从单链表中删除q结点
				free(q);
				return true;
			}
		}
	}
	else return false;
}

int main()
{
    LinkNode *lk;
    ElemType a[6]= {5,8,7,2,4,9};
    ElemType e;
    int i,x,choice;
    printf("第一步.创建循环单链表......\n");
    CreateListF(lk, a, 6);
    while(1){
    	printf("创建成功!请选择菜单执行相关操作\n");
	    printf("		1.销毁循环单链表\n");
	    printf("		2.判定循环单链表是否为空\n");
	    printf("		3.求循环单链表的长度\n");
	    printf("		4.输出循环单链表\n");
	    printf("		5.求循环单链表第i个位置上的元素\n");
	    printf("		6.查找循环单链表中元素e的位置\n");
	    printf("		7.在循环单链表第i个位置插入元素\n");
	    printf("		8.删除循环单链表第i个位置上的元素\n");
	    printf("		0.退出\n");
	    printf("		请输入你的选择:");
	    scanf("%d",&choice);
		switch(choice)
		{
			case 0: exit(0); 
			case 1: DestroyList(lk);
					printf("单链表销毁成功~~程序直接退出!!");
					exit(0);
			case 2: if(ListEmpty(lk))
						printf("单链表为空!");
					else
						printf("单链表不为空!");
					break;
			case 3: printf("该单链表长度为%d\n",ListLength(lk));
					break;
			case 4: printf("输出单链表:\n");
					DispList(lk);
					break;
			case 5: printf("请输入待查找元素的位置:");
					scanf("%d",&i);
					GetElem(lk, i, e);
					printf("第%d个位置上的元素为%d",i,e);
					break;
			case 6: printf("请输入要查找的元素:");
					scanf("%d",&x);
					printf("%d元素在单链表的第%d个位置\n",x,LocateElem(lk,x));
					break;
			case 7: printf("请输入要插入位置和值(空格隔开):");
					scanf("%d%d",&i,&x);
					ListInsert(lk,i,x);
					break;
			case 8: printf("请输入要删除的位置");
					scanf("%d",&i);
					ListDelete(lk, i, e);
					break;
		}
		printf("按任意键继续……");
		getchar();getchar();
    }
    return 0;
}
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h> 
typedef int ElemType;
typedef struct DNode//定义双链表结点类型
{
	ElemType data;
	struct DNode *prior;//指向前驱结点
	struct DNode *next;//指向后继结点
} DLinkNode;

//头插法建双链表
void CreateListF(DLinkNode *&L,ElemType a[],int n)
{
	/* L、L->next*/ 
	/* L、S、L->next*/ 
	DLinkNode *s;
	L = (DLinkNode *)malloc(sizeof(DLinkNode));
	L->prior = L->next=NULL;//前驱后继初始化时均赋NULL 
	for(int i = 0; i < n; i++)
	{	
		s = (DLinkNode *)malloc(sizeof(DLinkNode));
		s->data = a[i];
		s->next = L->next;//first
		if (L->next != NULL) 
			L->next->prior = s;//second
		L->next = s;//third
		s->prior = L;//forth
	}
}
//尾插法建双链表
void CreateListR(DLinkNode *&L,ElemType a[],int n)
{
	/*r*/
	/*r、s*/
	DLinkNode *s, *r;
	L = (DLinkNode *)malloc(sizeof(DLinkNode));
	L->prior = L->next = NULL;//前驱后继初始化时均赋NULL 
	r = L;//r始终指向终端结点,开始时指向头结点
	for(int i = 0; i < n; i++)
	{	 
		s = (DLinkNode *)malloc(sizeof(DLinkNode));
		s->data = a[i];
		r->next = s;//first 
		s->prior = r;//second
		r = s;//third 
	}
	r->next = NULL;//forth:尾结点next域置为NULL
}
void InitList(DLinkNode *&L)
{
	L = (DLinkNode *)malloc(sizeof(DLinkNode));
	L->prior = L->next = NULL;
}
void DestroyList(DLinkNode *&L)
{
	DLinkNode *pre = L,*p = pre->next;
	while (p!=NULL)
	{
		free(pre);
		pre = p;
		p = pre->next;
	}
	free(pre);
}
bool ListEmpty(DLinkNode *L)
{
	return(L->next==NULL);
}
int ListLength(DLinkNode *L)
{
	DLinkNode *p=L;
	int i=0;
	while (p->next!=NULL)
	{
		i++;
		p=p->next;
	}
	return(i);
}
void DispList(DLinkNode *L)
{
	DLinkNode *p=L->next;
	while (p!=NULL)
	{
		printf("%d ",p->data);
		p=p->next;
	}
	printf("\n");
}
bool GetElem(DLinkNode *L,int i,ElemType &e)
{
	int j=0;
	DLinkNode *p=L;
	if (i<=0) 
		return false;	
	while (j < i && p!=NULL)
	{
		j++;
		p = p->next;
	}
	if (p==NULL)
		return false;
	else
	{
		e=p->data;
		return true;
	}
}
int LocateElem(DLinkNode *L,ElemType e)
{
	int n=1;
	DLinkNode *p=L->next;
	while (p!=NULL && p->data!=e)
	{
		n++;
		p=p->next;
	}
	if (p==NULL)
		return(0);
	else
		return(n);
}
bool ListInsert(DLinkNode *&L, int i, ElemType e)
{
	/* L、L->next*/ 
	/* L、S、L->next*/ 
	int j=0;
	DLinkNode *p=L,*s;
	if (i<=0) 
		return false;//i错误返回假
	while (j<i-1 && p!=NULL)
	{
		j++;
		p=p->next;
	}
	if (p==NULL)//未找到第i-1个结点
		return false;
	else//找到第i-1个结点p
	{
		s = (DLinkNode *)malloc(sizeof(DLinkNode));	//创建新结点s
		s->data = e;	
		s->next = p->next;//first 
		if (p->next != NULL) 
			p->next->prior = s;//second 
		s->prior = p;//third 
		p->next = s;//forth 
		return true;
	}
}
bool ListDelete(DLinkNode *&L,int i,ElemType &e)
{
	/*注意找的是前驱,第i-1个结点*/ 
	/*p、q*/
	/*i-1、i*/ 
	int j = 0;
	DLinkNode *p = L,*q;
	if (i<=0) 
		return false;
	while (j < i-1 && p != NULL)
	{
		j++;
		p = p->next;
	}
	if(p == NULL)//未找到第i-1个结点
		return false;
	else//找到第i-1个结点p
	{
		q = p->next;//q指向要删除的结点
		if (q == NULL) 
			return false;//不存在第i个结点
		e = q->data;
		p->next = q->next;//从单链表中删除*q结点
		if(p->next!=NULL) 
			p->next->prior = p;
		free(q);
		return true;
	}
}

int main()
{
    DLinkNode *lk;
    ElemType a[6]= {5,8,7,2,4,9};
    ElemType e;
    int i,x,choice;
    printf("第一步.创建双链表......\n");
    CreateListF(lk, a, 6);
    while(1){
    	printf("创建成功!请选择菜单执行相关操作\n");
	    printf("		1.销毁双链表\n");
	    printf("		2.判定双链表是否为空\n");
	    printf("		3.求双链表的长度\n");
	    printf("		4.输出双链表\n");
	    printf("		5.求双链表第i个位置上的元素\n");
	    printf("		6.查找双链表中元素e的位置\n");
	    printf("		7.在双链表第i个位置插入元素\n");
	    printf("		8.删除双链表第i个位置上的元素\n");
	    printf("		0.退出\n");
	    printf("		请输入你的选择:");
	    scanf("%d",&choice);
		switch(choice)
		{
			case 0: exit(0); 
			case 1: DestroyList(lk);
					printf("双链表销毁成功~~程序直接退出!!");
					exit(0);
			case 2: if(ListEmpty(lk))
						printf("双链表为空!");
					else
						printf("双链表不为空!");
					break;
			case 3: printf("该双链表长度为%d\n",ListLength(lk));
					break;
			case 4: printf("输出双链表:\n");
					DispList(lk);
					break;
			case 5: printf("请输入待查找元素的位置:");
					scanf("%d",&i);
					GetElem(lk, i, e);
					printf("第%d个位置上的元素为%d",i,e);
					break;
			case 6: printf("请输入要查找的元素:");
					scanf("%d",&x);
					printf("%d元素在双链表的第%d个位置\n",x,LocateElem(lk,x));
					break;
			case 7: printf("请输入要插入位置和值(空格隔开):");
					scanf("%d%d",&i,&x);
					ListInsert(lk,i,x);
					break;
			case 8: printf("请输入要删除的位置");
					scanf("%d",&i);
					ListDelete(lk, i, e);
					break;
		}
		printf("按任意键继续……");
		getchar();getchar();
    }
    return 0;
}
//循环双链表基本运算算法
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h> 
typedef int ElemType;
typedef struct DNode//定义双链表结点类型
{
	ElemType data;
	struct DNode *prior;//指向前驱结点
	struct DNode *next;//指向后继结点
} DLinkNode;

//头插法建立循环双链表
void CreateListF(DLinkNode *&L,ElemType a[],int n)
{
	DLinkNode *s;
	int i;
	L = (DLinkNode *)malloc(sizeof(DLinkNode));
	L->next = NULL;
	for(i = 0; i < n; i++)
	{	
		s = (DLinkNode *)malloc(sizeof(DLinkNode));
		s->data = a[i];
		s->next = L->next;//first
		if (L->next != NULL) 
			L->next->prior = s;//second 
		L->next = s;//third
		s->prior = L;//forth
	}
	s = L->next;	
	while (s->next!=NULL)//查找尾结点,使s指向它
		s = s->next;
 	s->next = L;//first:使尾结点s的next域指向头结点
	L->prior = s;//second:头结点的prior域指向尾结点

}
void CreateListR(DLinkNode *&L,ElemType a[],int n)
//尾插法建立循环双链表
{
	DLinkNode *s,*r;
	int i;
	L = (DLinkNode *)malloc(sizeof(DLinkNode));
	L->next=NULL;
	r = L;//r始终指向尾结点,开始时指向头结点
	for(i = 0; i < n; i++)
	{	
		s = (DLinkNode *)malloc(sizeof(DLinkNode));
		s->data = a[i];
		r->next = s;//first 
		s->prior = r;//second 
		r = s;//third 
	}
	r->next = L;//first:尾结点next域指向头结点
	L->prior = r;//second:头结点的prior域指向尾结点
}
void InitList(DLinkNode *&L)
{
	L = (DLinkNode *)malloc(sizeof(DLinkNode));
	L->prior = L->next = L;
}
void DestroyList(DLinkNode *&L)
{
	DLinkNode *p = L, *q = p->next;
	while(q!=L)
	{
		free(p);
		p = q;
		q = p->next;
	}
	free(p);
}
bool ListEmpty(DLinkNode *L)
{
	return(L->next==L);
}
int ListLength(DLinkNode *L)
{
	DLinkNode *p = L;
	int i = 0;
	while (p->next!=L)
	{
		i++;
		p = p->next;
	}
	return(i);
}
void DispList(DLinkNode *L)
{
	DLinkNode *p = L->next;
	while (p!=L)
	{
		printf("%d ",p->data);
		p = p->next;
	}
	printf("\n");
}
bool GetElem(DLinkNode *L, int i, ElemType &e)
{
	int j = 0;
	DLinkNode *p;
	if (L->next != L)//双链表不为空表时
	{
		if (i==1)
		{
			e = L->next->data;
			return true;
		}
		else//i不为1时
		{
			p = L->next;
			while (j<i-1 && p!=L)
			{
				j++;
				p = p->next;
			}
			if(p == L)
				return false;
			else
			{
				e = p->data;
				return true;
			}
		}
	}
	else//双链表为空表时
		return 0;
}
int LocateElem(DLinkNode *L,ElemType e)
{
	int n = 1;
	DLinkNode *p = L->next;
	while (p!=NULL && p->data!=e)
	{
		n++;
		p = p->next;
	}
	if (p == NULL)
		return(0);
	else
		return(n);
}
bool ListInsert(DLinkNode *&L,int i,ElemType e)
{
	int j = 0;
	DLinkNode *p = L,*s;
	if (p->next==L)//原双链表为空表时
	{	
		/* p、s */ 
		s = (DLinkNode *)malloc(sizeof(DLinkNode));
		s->data = e;
		p->next = s;//first:即p->next指向p/L变为指向s 
		s->next = p;//second:即s->next指回p 
		p->prior = s;//third :即p->prior指向p/l变为指向s 
		s->prior = p;//forth :s->prior指回p 
		return true;
	}
	else if(i == 1)//原双链表不为空表但i=1时
	{
		/* p、p->next*/ 
		/* p、s、p->next*/ 
		s = (DLinkNode *)malloc(sizeof(DLinkNode));	//创建新结点s
		s->data = e;
		s->next = p->next;//first 
		p->next = s;//second 
		s->next->prior = s;//third 
		s->prior = p;//forth 
		return true;
	}
	else//插入i位置不为1时 
	{	
		p = L->next;
		while (j < i-2 && p!=L)//第i-1个结点的序标为i-2 
		{	
			j++;
			p = p->next;
		}
		if(p==L)//未找到第i-1个结点
			return false;
		else//找到第i-1个结点
		{
			s = (DLinkNode *)malloc(sizeof(DLinkNode));	
			s->data = e;	
			s->next = p->next;//first 
			if (p->next!=NULL) 
				p->next->prior=s;//second 
			s->prior = p;//third 
			p->next = s;//forth 
			return true;
		}
	}
}
bool ListDelete(DLinkNode *&L,int i,ElemType &e)
{
	int j = 0;
	DLinkNode *p=L,*q;
	if (p->next!=L)//原双链表不为空表时
	{	
		if(i==1)//i==1时
		{	
			q=L->next;//删除第1个结点
			e=q->data;
			L->next=q->next;
			q->next->prior=L;
			free(q);
			return true;
		}
		else//i不为1时
		{	
			p=L->next;
			while(j<i-2 && p!=NULL)//第i-1个结点的序标为i-2 
			{
				j++;
				p=p->next;
			}
			if(p==NULL)//未找到第i-1个结点
				return false;
			else//找到第i-1个结点p
			{
				q=p->next;//q指向要删除的结点
				if (q==NULL) 
					return 0;//不存在第i个结点
				e=q->data;
				p->next=q->next;//从单链表中删除q结点
				if (p->next!=NULL) p->next->prior=p;
				free(q);
				return true;
			}
		}
	}
	else return false;//原双链表为空表时
}

int main()
{
    DLinkNode *lk;
    ElemType a[6]= {5,8,7,2,4,9};
    ElemType e;
    int i,x,choice;
    printf("第一步.创建循环双链表......\n");
    CreateListF(lk, a, 6);
    while(1){
    	printf("创建成功!请选择菜单执行相关操作\n");
	    printf("		1.销毁循环双链表\n");
	    printf("		2.判定循环双链表是否为空\n");
	    printf("		3.求循环双链表的长度\n");
	    printf("		4.输出循环双链表\n");
	    printf("		5.求循环双链表第i个位置上的元素\n");
	    printf("		6.查找循环双链表中元素e的位置\n");
	    printf("		7.在循环双链表第i个位置插入元素\n");
	    printf("		8.删除循环双链表第i个位置上的元素\n");
	    printf("		0.退出\n");
	    printf("		请输入你的选择:");
	    scanf("%d",&choice);
		switch(choice)
		{
			case 0: exit(0); 
			case 1: DestroyList(lk);
					printf("循环双链表销毁成功~~程序直接退出!!");
					exit(0);
			case 2: if(ListEmpty(lk))
						printf("循环双链表为空!");
					else
						printf("循环双链表不为空!");
					break;
			case 3: printf("该循环双链表长度为%d\n",ListLength(lk));
					break;
			case 4: printf("输出循环双链表:\n");
					DispList(lk);
					break;
			case 5: printf("请输入待查找元素的位置:");
					scanf("%d",&i);
					GetElem(lk, i, e);
					printf("第%d个位置上的元素为%d",i,e);
					break;
			case 6: printf("请输入要查找的元素:");
					scanf("%d",&x);
					printf("%d元素在循环双链表的第%d个位置\n",x,LocateElem(lk,x));
					break;
			case 7: printf("请输入要插入位置和值(空格隔开):");
					scanf("%d%d",&i,&x);
					ListInsert(lk,i,x);
					break;
			case 8: printf("请输入要删除的位置");
					scanf("%d",&i);
					ListDelete(lk, i, e);
					break;
		}
		printf("按任意键继续……");
		getchar();getchar();
    }
    return 0;
}

5.链栈 Listack

//链栈基本运算算法
#include <stdio.h>
#include <stdlib.h> 
#include <malloc.h>
typedef int ElemType;
typedef struct linknode
{	
	ElemType data;				//数据域
	struct linknode *next;		//指针域
} LinkStNode;					//链栈类型
void InitStack(LinkStNode *&s)
{
	s=(LinkStNode *)malloc(sizeof(LinkStNode));
	s->next=NULL;
}
void DestroyStack(LinkStNode *&s)
{
	LinkStNode *p=s->next;
	while (p!=NULL)
	{	
		free(s);
		s=p;
		p=p->next;
	}
	free(s);	//s指向尾结点,释放其空间
}
bool StackEmpty(LinkStNode *s)
{
	return(s->next==NULL);
}
int StackLength(LinkStNode *s){
	int i = 0;
	while(s->next != NULL){
		i++;
		s = s -> next;
	}
	return i;
}

void Push(LinkStNode *&s,ElemType e)
{
	/*头插法*/ 
	LinkStNode *p;
	p=(LinkStNode *)malloc(sizeof(LinkStNode));
	p->data=e;				//新建元素e对应的结点p
	p->next=s->next;		//插入p结点作为开始结点
	s->next=p;
}
bool Pop(LinkStNode *&s,ElemType &e)//出栈,由于头插法,因此很方便 
{	
	LinkStNode *p;
	if (s->next==NULL)		//栈空的情况
		return false;
	p=s->next;				//p指向开始结点
	e=p->data;
	s->next=p->next;		//删除p结点
	free(p);				//释放p结点
	return true;
}
bool GetTop(LinkStNode *s,ElemType &e)
{	
	if (s->next==NULL)		//栈空的情况
		return false;
	e=s->next->data;
	return true;
}


int main(){
	LinkStNode *s;
	ElemType e;
	int i, x, choice;
	printf("第一步.创建链栈......\n");
	InitStack(s);
    while(1){
    	printf("创建成功!请选择菜单执行相关操作\n");
	    printf("		1.销毁链栈\n");
	    printf("		2.判定链栈是否为空\n");
	    printf("		3.求链栈的长度\n");
	    printf("		4.输入入栈元素进栈\n");
	    printf("		5.使栈顶元素出栈\n");
	    printf("		6.获取栈顶元素\n");
	    printf("		0.退出\n");
	    printf("		请输入你的选择:");
	    scanf("%d",&choice);
		switch(choice)
		{
			case 0: exit(0); 
			case 1: DestroyStack(s);
					printf("链栈销毁成功~~程序直接退出!!");
					exit(0);
			case 2: if(StackEmpty(s))
						printf("链栈为空!");
					else
						printf("链栈不为空!");
					break;
			case 3: printf("该链栈长度为%d\n",StackLength(s));
					break;
			case 4: printf("请输入入栈元素:");
					fflush(stdin);
					scanf("%d",&e);//根据ElemType类型 
					Push(s, e);
					break;
			case 5: printf("令栈顶元素出栈:");
					Pop(s, e); 
					printf("出栈元素为%d\n",e);//根据ElemType类型 
					break;
			case 6: printf("获取栈顶元素:");
					GetTop(s, e);
					printf("栈顶元素为%d\n",e);//根据ElemType类型 
					break;
		}
		printf("按任意键继续……");
		getchar();getchar();
    }
    return 0;
}

二、其它算法

  1. 如何判断链表是否有环,以及如何求该入环点

  2. 如何判断两条链表是否有交点,以及如何求该交点

  3. 两个循环链表合并为一张表

posted @ 2019-10-09 10:28  解尼  阅读(251)  评论(0编辑  收藏  举报