数据结构线性表的链式存储结构(单链表)的表示及其基本操作

头文件 宏定义 部分变量

#include <stdio.h>
#include <stdlib.h>
#define OVERFLOW -2 
#define ERROR 0
#define OK 1

typedef int Status;
typedef int Elemtype;
typedef struct LNode{
	Elemtype data;
	struct LNode * next;
}LNode,* LinkList;
Elemtype flag=0;//flag用于判断链表是否初始化 0:未初始化 1:已初始化
Elemtype cflag=0;//cflag用于判断链表是否为空 0:空  1:不空 

初始化一个空的链表

注:L是指向头结点的指针(也叫头指针,不知道什么是头结点,首元结点,好吧,简要说下)
首元结点:是指链表中用来存储数据元素的节点中的第一个节点
头结点:指在链表的首元节点之前附设的一个结点,数据域内只放空表标 志和表长等信息,也可以什么都不放
什么?为什么要这样设置?
这。。。。。。。
当然是因为这是前辈们的智慧喽
单链表头结点、首元节点详解
嗯,为什么形参定义是LinkList * L呢?
因为我们要改变头指针的指向,分配一个大小是LNode的内存空间,让头指针指向它,如果不需要改变头指针的指向,我们就只需要定义成LinkList L即可,然后让头结点的指针域为空,代表这是个空表,返回OK代表初始化成功。

Status InitList(LinkList * L)
{
	*L=(LinkList)malloc(sizeof(LNode));
	if(!*L))
	{
		exit(OVERFLOW);
	}
	(*L)->next=NULL;
	return OK;
} 

调用

case 1:
				printf("初始化或重置链表\n");
				printf("初始化请按1\n");
				printf("重置链表请按2\n");
				scanf("%d",&elem);
				if(elem==1)
				{				 
				  flag=InitList(&L);
				  if(flag==0)
				    printf("初始化失败\n");
				  else
				    printf("初始化成功\n"); 	 
				} 
				if(elem==2)
				{
					if(flag==1)
					{
						cflag=ClearList(L);
					    printf("链表已清空\n");
					}else
					{
						printf("链表未初始化\n");
					}  					  
				}
				system("pause");
				break;

重置链表(清空链表)

使p指向首元结点,如果p不为空,进入循环,让q指向p的后继结点,然后释放p所指向的 结点,p再移到下一个结点,q就像一个引路人,引着 p遍历完链表,释放所有的元素结点。当p指向尾结点进入循环后,q就为空,释放p后,p=q ,p为空,不再执行循环,所有元素结点均被清空。令L的指针域为空,返回ERROR代表空表标志

Status ClearList(LinkList L)
{
	LinkList p,q;
	p=L->next;
	while(p)
	{
		q=p->next;
		free(p);
		p=q;
	}
	L->next=NULL;
	return ERROR;
}

调用

case 3:
			    if(flag!=0)
				{
					cflag=ClearList(L);
					printf("链表已清空\n");					
				}else
				{
					printf("链表未初始化\n");
				}
				system("pause");
				break;

销毁链表

遍历,然后释放每个结点所分配的空间。

Status DestroyList(LinkList * L) 
{
	LinkList p,q;
	p=(*L)->next;
	while(p)
	{
		q=p->next;
		free(p);
		p=q;
	}
	p=*L;
	free(p);
	return ERROR;	
}

调用

case 2:
				if(flag!=0)
				{
					printf("销毁链表\n");
					flag=DestroyList(&L);
					printf("销毁成功\n");
				}else
				{
					printf("链表未初始化\n");
				}
				system("pause");
				break;

求链表的长度

定义一个计数器count,遍历到每个结点时,count++;直到遍历到最后一个结点,尾结点的指针域(为空)赋值给p,count+1;无法再次进行循环,返回count;

Status ListLength(LinkList L)
{
	Elemtype count=0;
	LinkList p;
	p=L->next;
	while(p)
	{
		p=p->next;
		count++;
	}
	return count; 
}

调用

case 4:
			    if(flag!=0)
				{
					printf("链表的长度为%d\n",ListLength(L));
				}else
				{
					printf("链表未初始化\n");
				}
				system("pause");
				break;

求指定位置的元素值

定义一个指针p指向头结点,当i=1时,p=p->next,指向第一个结点,当i=position时,指向所找的位置,返回该位置的数据域即可。

Status GetElem(LinkList L,Elemtype position)
{
	Elemtype i;
	LinkList p;
	p=L;
	for(i=1;i<=position;i++)
	{
		p=p->next;
	}
	return p->data;
} 

调用

case 5:
			    if(flag!=0)
				{
					printf("请输入你所查找的位置\n");
					scanf("%d",&position);
					if(position<=0||position>ListLength(L))
	                {
	                   	printf("不存在这个位置\n");
					}else
					{
						elem=GetElem(L,position);
					    printf("该位置上的元素是%d\n",elem);
					}					
			    }else
				{
					printf("链表未初始化\n");
				} 
				system("pause");
				break;

求指定元素的位序

求位序,我们就要定义一个position,通过遍历结点,找到与elem相等的位置,返回该位序。当position等于1时,p指向第一个结点,判断,若不等,则指向第二个结点,position+1;直到找到position,返回position即可。

Status LocateElem(LinkList L,Elemtype elem)
{
	Elemtype position=1;
	LinkList p;
	p=L->next;
	while(p)
	{
		if(elem==p->data)
		   break;
		p=p->next;
		position++;   
	}
	return position;
}

调用

case 6:
			    if(flag!=0)
				{
					printf("请输入你所查找的元素\n");
					scanf("%d",&elem);
					position=LocateElem(L,elem);				
					if(position>ListLength(L))
					{
						printf("链表中不存在该元素\n");
					}else
				    {			    	
				    	printf("该元素在链表中的位置是%d\n",position);
					}
				}
				system("pause");
				break;

求输入元素的直接前驱

定义指向节点的指针p,q;使P指向首元节点,判断首元节点的数据域是否与elem相等,相等则结束调用,返回ERROR,若不相等则遍历链表,使p指向要与elem相比较的节点,q指向p的前驱节点,若p->data=elem,结束循环,并返回q->data,如果elem不存在于链表中,p指向最后一个节点后,将会再次进入循环,最后一个节点的指针域(null)会赋值给p,结束循环,那么,如果p==NULL,则代表链表中不存在elem

Status PriorElem(LinkList L,Elemtype elem)
{
	LinkList p,q;
	p=L->next;
	if(p->data==elem)
	   return ERROR;
	while(p)
	{
		q=p;
		p=p->next;
		if(p==NULL)
		  break;
		if(p->data==elem)
		   break;		   
	}
	if(p==NULL)
	  return ERROR;
	return q->data;   
} 

调用

case 7:
			    if(flag!=0)
				{
					printf("请输入数字:\n");
					scanf("%d",&elem);
	                pelem=PriorElem(L,elem);
					if(pelem==ERROR)
					{
						printf("该元素不存在前驱或者不存在该元素\n");
					}else
					{
						printf("该元素的前驱是%d.\n",pelem);
					}    
				}else
				{
					printf("链表未初始化\n");
				}
				system("pause");
				break;

求输入元素的后继

定义指向节点的指针p,q;使P指向首元节点,如果p!=null,则进入循环,令q始终指向p的后继结点,判断p->data是否等于elem, 若p->data=elem,结束循环,并返回q->data。如果elem是链表尾节点的数据域中的元素,则q==null(此时p指向最后一个节点), 如果链表中不存在elem,则p=null结束循环,返回ERROR

Status NextElem(LinkList L,Elemtype elem)
{
	LinkList p,q;
	p=L->next;
	while(p)
	{
		q=p->next;
		if(p->data==elem)
		{
			break;
		}		   
		p=q;   
	}
	if(p==NULL||q==NULL)
	   return ERROR;
	return q->data;   
}

调用

case 8:
			    if(flag!=0)
				{
					printf("请输入数字:\n");
					scanf("%d",&elem);
					nelem=NextElem(L,elem);
					if(nelem==ERROR)
					{
						printf("该元素不存在后继或者不存在该元素\n");
					}else
					{
						printf("该元素的后继是%d.\n",nelem);
					}	
				}else
				{
					printf("链表未初始化\n");
				}
				system("pause");
				break;

插入元素

定义俩个可以指向节点的指针p,q,创建一个新的节点,使p指向新节点,将elem赋值给新节点的数据域,q指向头结点,遍历链表, 使q指向待插入位置的前驱节点,找到后,将插入位置的前驱节点的指针域赋值给新节点的指针域,然后将插入位置的前驱节点的指针域指向新节点

void ListInsert(LinkList L,Elemtype position,Elemtype elem) 
{
	Elemtype i;
	LinkList p,q;
	p=(LinkList)malloc(sizeof(LNode));
	p->data=elem;
	q=L;
	for(i=1;i<position;i++)//i=1时,q指向第一个节点,i=2时,q指向第二个节点
	{//所以当i=position-1时,q指向待插入位置的前驱节点 
		q=q->next;
	}
	p->next=q->next;
	q->next=p;	
}

调用

case 9:
			    if(flag!=0)
				{
					printf("请输入你所要插入的位置:\n");
					scanf("%d",&position);
					if(position<=0||position>ListLength(L)+1)
					{
						printf("位置错误\n");
					}else
					{
						printf("请输入数字:\n");
						scanf("%d",&elem);
						ListInsert(L,position,elem);
						printf("插入成功\n");
					}						
				}else
				{
					printf("链表未初始化\n");
				}
				system("pause");
				break;

删除指定位置的元素

想要删除某个节点,我们让它的前驱节点的指针域指向其后继节点,然后释放要删除的节点的空间即可
怎么遍历呢?定义一个变量i,记录当前遍历到的节点位置,直到遍历到待删除节点,进入循环,循环体语句结束
结束之后,q指向待删除节点的前驱节点,p指向待删除节点,i++,退出循环。

void ListDelete(LinkList L,Elemtype position)
{
	Elemtype i=1;
	LinkList p,q;
	p=L;
	while(p&&i<=position)
	{
		q=p;
		p=p->next;
		i++;
	} 
	q->next=p->next;
	free(p);
} 

调用

case 10:
			    if(flag!=0&&cflag==1)
				{
					printf("请输入你所要删除的位置:\n");
					scanf("%d",&position);
					if(position<=0||position>ListLength(L))
					{
						printf("位置错误\n");
					}else
					{
						ListDelete(L,position);
						printf("删除成功\n");
					}						
				}else
				{
					printf("链表未初始化或者链表为空\n");
				}
				system("pause");
				break;

输出链表

依次遍历每个结点,输出其数据域即可。

void ListTraverse(LinkList L)
{
	LinkList p;
	p=L->next;
	while(p)
	{
		printf("%d ",p->data);
		p=p->next;
	}
} 

调用

	case 11:
			    if(flag!=0)
				{
					printf("输出链表\n");					
					ListTraverse(L);
					printf("输出完成\n");	
				}else
				{
					printf("链表未初始化\n");
				}
				system("pause");
				break;

用头插法输入元素

定义俩个指向链表结点的指针,p用来存储分配的大小为LNode空间的首地址,q用来给p指向的结点的指针域赋值(即上一次分配的结点的首地址),因为(头插法)输入的第一个元素为链表的尾结点,所以得将q初始化为null.存储在尾结点的指针域内。如果输入-1,代表结束输入。
我们来看下循环体内的语句,首先,分配新空间,将首地址赋给p,判断是否分配成功,成功后,用户输入数字,这时,在判断数字是否为-1,是的话 就要释放刚生成的空间,并退出循环。不是的话,将elem赋给新结点的数据域,将q赋给新结点的指针域之后,令q指向新结点,(记录新结点的地址,为了让下次循环生成的结点能连上上一次循环生成的结点),结束循环,将q的值赋值给头结点,返回OK,代表元素录入完成。

Status CreateList(LinkList L)
{
	LinkList p,q;
	q=NULL;
	Elemtype elem;
	while(1)
	{
		p=(LinkList)malloc(sizeof(LNode));
		if(!p)
		  exit(OVERFLOW);
		scanf("%d",&elem); 
		if(elem==-1)
		{
		    break;
		    free(p);
		}
		p->data=elem;
		p->next=q;
		q=p;		
	}
	L->next=q;
	return OK;
 }

调用

case 12:
				if(flag!=0)
				{
					printf("请输入数字:\n");
					printf("如果输入-1,代表结束\n");
					cflag=CreateList(L);					
				}else
				{
					printf("链表未初始化\n");
				}
				system("pause");
			    break;	

逆置链表

定义指针p,q,p用来遍历原链表,q用来存储新结点的地址,并连接新链表。因为原链表有p指向,所以可以将头指针L解放出来,令头结点的指针域为空,作为新链表的头指针。
while (p )代表 将原链表的结点依次遍历,直到遍历到尾结点,进入循环。
(第一次循环)分配新的结点,令q指向新结点,考虑异常情况后,将原链表的第一个结点的数据域赋值给新结点的指针域,(为了节省空间,我们仍用原链表的头指针),将L->next赋值给新结点 的指针域(参考头插法),将新结点的首地址q赋值给头结点的指针域,p再指向原链表的下一个节点。
(第二次循环)依旧分配新的空间,将原链表第二个节点的数据域赋值给新结点的数据域,将上一个新结点的地址(即L->next)赋给新结点的指针域,然后用p->next指向新结点,p遍历到原链表的下一个结点。

void NegaListTraverse(LinkList L)
{
	LinkList p,q;
	p=L->next;
	L->next=NULL;
	while(p)
	{		
		q=(LinkList)malloc(sizeof(LNode));
		if(!q)
		  exit(OVERFLOW);
		q->data=p->data;
		q->next=L->next;
		L->next=q;  
        p=p->next;
	}
}

调用

case 13:
				if(flag!=0)
				{
					printf("单链表的逆序排放\n");					
					NegaListTraverse(L);					
				}else
				{
					printf("链表未初始化\n");
				}
				system("pause");
			    break;

完整代码

#include <stdio.h>
#include <stdlib.h>
#define OVERFLOW -2 
#define ERROR 0
#define OK 1

typedef int Status;
typedef int Elemtype;
typedef struct LNode{
	Elemtype data;
	struct LNode * next;
}LNode,* LinkList;
Elemtype flag=0;//flag用于判断链表是否初始化 0:未初始化 1:已初始化
Elemtype cflag=0;//cflag用于判断链表是否为空 0:空  1:不空 

Status InitList(LinkList * L);//初始化一个空的链表
Status ClearList(LinkList L);//重置链表 
Status DestroyList(LinkList * L);//销毁链表
Status ListLength(LinkList L);//求链表的长度
Status GetElem(LinkList L,Elemtype position);//求指定位置的元素值 
Status LocateElem(LinkList L,Elemtype elem);//求指定元素的位序 
Status PriorElem(LinkList L,Elemtype elem);//求前驱 
Status NextElem(LinkList L,Elemtype elem);//求后继
void ListInsert(LinkList L,Elemtype position,Elemtype elem);//插入节点  
void ListDelete(LinkList L,Elemtype elem);//删除节点 
Status CreateList(LinkList L);//存储元素
void ListTraverse(LinkList L);//遍历链表
void NegaListTraverse(LinkList L);//逆置链表 
int main()
{
	Elemtype fun;//fun是用户选择的功能 
    Elemtype position;
    Elemtype elem;
    Elemtype pelem;//前驱 
    Elemtype nelem;//后继  
	LinkList L=NULL;	
	while(1)
	{//while的左括号 
	    printf("输出菜单\n");
	    printf("1.初始化或重置链表\n");
	    printf("2.销毁链表\n");
	    printf("3.清空链表\n");
    	printf("4.链表长度\n");
    	printf("5.指定位置的元素值\n");
    	printf("6.链表已存在元素的位序\n");
    	printf("7.求输入元素的直接前驱\n");
    	printf("8.求输入元素的直接后继\n");
    	printf("9.在第i个位置插入一个元素\n");
    	printf("10.删除第i个元素\n");
    	printf("11.输出所有的链表元素\n");
    	printf("12.初始化并用头插法(或尾插法)输入元素\n");
    	printf("13.实现单链表的逆序存放\n");
		printf("请输入数字选择你所选择的操作\n");
		printf("输入负数退出程序\n");
		scanf("%d",&fun);
		if(fun<0)
		   break;	
		switch(fun)
		{//switch的左括号 
			case 1:
				printf("初始化或重置链表\n");
				printf("初始化请按1\n");
				printf("重置链表请按2\n");
				scanf("%d",&elem);
				if(elem==1)
				{				 
				  flag=InitList(&L);
				  if(flag==0)
				    printf("初始化失败\n");
				  else
				    printf("初始化成功\n"); 	 
				} 
				if(elem==2)
				{
					if(flag==1)
					{
						cflag=ClearList(L);
					    printf("链表已清空\n");
					}else
					{
						printf("链表未初始化\n");
					}  					  
				}
				system("pause");
				break;
			case 2:
				if(flag!=0)
				{
					printf("销毁链表\n");
					flag=DestroyList(&L);
					printf("销毁成功\n");
				}else
				{
					printf("链表未初始化\n");
				}
				system("pause");
				break;
			case 3:
			    if(flag!=0)
				{
					cflag=ClearList(L);
					printf("链表已清空\n");					
				}else
				{
					printf("链表未初始化\n");
				}
				system("pause");
				break;
			case 4:
			    if(flag!=0)
				{
					printf("链表的长度为%d\n",ListLength(L));
				}else
				{
					printf("链表未初始化\n");
				}
				system("pause");
				break;
			case 5:
			    if(flag!=0)
				{
					printf("请输入你所查找的位置\n");
					scanf("%d",&position);
					if(position<=0||position>ListLength(L))
	                {
	                   	printf("不存在这个位置\n");
					}else
					{
						elem=GetElem(L,position);
					    printf("该位置上的元素是%d\n",elem);
					}					
			    }else
				{
					printf("链表未初始化\n");
				} 
				system("pause");
				break;
			case 6:
			    if(flag!=0)
				{
					printf("请输入你所查找的元素\n");
					scanf("%d",&elem);
					position=LocateElem(L,elem);				
					if(position>ListLength(L))
					{
						printf("链表中不存在该元素\n");
					}else
				    {			    	
				    	printf("该元素在链表中的位置是%d\n",position);
					}
				}
				system("pause");
				break;
			case 7:
			    if(flag!=0)
				{
					printf("请输入数字:\n");
					scanf("%d",&elem);
	                pelem=PriorElem(L,elem);
					if(pelem==ERROR)
					{
						printf("该元素不存在前驱或者不存在该元素\n");
					}else
					{
						printf("该元素的前驱是%d.\n",pelem);
					}    
				}else
				{
					printf("链表未初始化\n");
				}
				system("pause");
				break;
			case 8:
			    if(flag!=0)
				{
					printf("请输入数字:\n");
					scanf("%d",&elem);
					nelem=NextElem(L,elem);
					if(nelem==ERROR)
					{
						printf("该元素不存在后继或者不存在该元素\n");
					}else
					{
						printf("该元素的后继是%d.\n",nelem);
					}	
				}else
				{
					printf("链表未初始化\n");
				}
				system("pause");
				break;
			case 9:
			    if(flag!=0)
				{
					printf("请输入你所要插入的位置:\n");
					scanf("%d",&position);
					if(position<=0||position>ListLength(L)+1)
					{
						printf("位置错误\n");
					}else
					{
						printf("请输入数字:\n");
						scanf("%d",&elem);
						ListInsert(L,position,elem);
						printf("插入成功\n");
					}						
				}else
				{
					printf("链表未初始化\n");
				}
				system("pause");
				break;
			case 10:
			    if(flag!=0&&cflag==1)
				{
					printf("请输入你所要删除的位置:\n");
					scanf("%d",&position);
					if(position<=0||position>ListLength(L))
					{
						printf("位置错误\n");
					}else
					{
						ListDelete(L,position);
						printf("删除成功\n");
					}						
				}else
				{
					printf("链表未初始化或者链表为空\n");
				}
				system("pause");
				break;
			case 11:
			    if(flag!=0)
				{
					printf("输出链表\n");					
					ListTraverse(L);
					printf("输出完成\n");	
				}else
				{
					printf("链表未初始化\n");
				}
				system("pause");
				break;						
			case 12:
				if(flag!=0)
				{
					printf("请输入数字:\n");
					printf("如果输入-1,代表结束\n");
					cflag=CreateList(L);					
				}else
				{
					printf("链表未初始化\n");
				}
				system("pause");
			    break;		
			case 13:
				if(flag!=0)
				{
					printf("单链表的逆序排放\n");					
					NegaListTraverse(L);					
				}else
				{
					printf("链表未初始化\n");
				}
				system("pause");
			    break;						 
		}//switch的右括号
		system("cls");		
	}//while的右括号 
	return 0;
}
//初始化一个空的链表
Status InitList(LinkList * L)
{
	*L=(LinkList)malloc(sizeof(LNode));
	if(!*L)
	{
		exit(OVERFLOW);
	}
	(*L)->next=NULL;
	return OK;
} 
//重置链表
Status ClearList(LinkList L)
{
	LinkList p,q;
	p=L->next;
	while(p)
	{
		q=p->next;
		free(p);
		p=q;
	}
	L->next=NULL;
	return ERROR;
}
//销毁链表 
Status DestroyList(LinkList * L) 
{
	LinkList p,q;
	p=(*L)->next;
	while(p)
	{
		q=p->next;
		free(p);
		p=q;
	}
	p=*L;
	free(p);
	return ERROR;	
}
//求链表的长度
Status ListLength(LinkList L)
{
	Elemtype count=0;
	LinkList p;
	p=L->next;
	while(p)
	{
		p=p->next;
		count++;
	}
	return count; 
}
//求指定位置的元素值
Status GetElem(LinkList L,Elemtype position)
{
	Elemtype count=0;
	Elemtype i;
	LinkList p;
	p=L;
	for(i=1;i<=position;i++)
	{
		p=p->next;
	}
	return p->data;
} 
//求指定元素的位序
Status LocateElem(LinkList L,Elemtype elem)
{
	Elemtype position=1;
	LinkList p;
	p=L->next;
	while(p)
	{
		if(elem==p->data)
		   break;
		p=p->next;
		position++;   
	}
	return position;
} 
//求输入元素的直接前驱
//定义指向节点的指针p,q;使P指向首元节点,判断首元节点的数据域是否与elem相等,相等则结束调用,返回ERROR,若不相等则遍历链表,使p指向要与elem相比较的节点,q指向
//p的前驱节点,若p->data==elem,结束循环,并返回q->data,如果elem不存在于链表中,p指向最后一个节点后,将会再次进入循环,最后一个节点的指针域(null)会赋值给p,
//结束循环,那么,如果p==NULL,则代表链表中不存在elem 
Status PriorElem(LinkList L,Elemtype elem)
{
	LinkList p,q;
	p=L->next;
	if(p->data==elem)
	   return ERROR;
	while(p)
	{
		q=p;
		p=p->next;
		if(p==NULL)
		  break;
		if(p->data==elem)
		   break;		   
	}
	if(p==NULL)
	  return ERROR;
	return q->data;   
} 
//求输入元素的后继
//定义指向节点的指针p,q;使P指向首元节点,如果p!=null,则进入循环,令q始终指向p的后继结点,判断p->data是否等于elem, 若p->data==elem,结束循环,并返回q->data
//如果elem是链表尾节点的数据域中的元素,则q==null(此时p指向最后一个节点), 如果链表中不存在elem,则p==null
//结束循环,返回ERROR 
Status NextElem(LinkList L,Elemtype elem)
{
	LinkList p,q;
	p=L->next;
	while(p)
	{
		q=p->next;
		if(p->data==elem)
		{
			break;
		}		   
		p=q;   
	}
	if(p==NULL||q==NULL)
	   return ERROR;
	return q->data;   
}
//插入元素
//定义俩个可以指向节点的指针p,q,创建一个新的节点,使p指向新节点,将elem赋值给新节点的数据域,q指向头结点,遍历链表, 
//使q指向待插入位置的前驱节点,找到后,将
//插入位置的前驱节点的指针域赋值给新节点的指针域,然后将插入位置的前驱节点的指针域指向新节点 
void ListInsert(LinkList L,Elemtype position,Elemtype elem) 
{
	Elemtype i;
	LinkList p,q;
	p=(LinkList)malloc(sizeof(LNode));
	p->data=elem;
	q=L;
	for(i=1;i<position;i++)//i=1时,q指向第一个节点,i=2时,q指向第二个节点
	{//所以当i=position-1时,q指向待插入位置的前驱节点 
		q=q->next;
	}
	p->next=q->next;
	q->next=p;	
}
//删除指定位置的元素
/* 想要删除某个节点,我们让它的前驱节点的指针域指向其后继节点,然后释放要删除的节点的空间即可
怎么遍历呢?定义一个变量i,记录当前遍历到的节点位置,直到遍历到待删除节点,进入循环,循环体语句结束
结束之后,q指向待删除节点的前驱节点,p指向待删除节点,i++,退出循环, 
*/
void ListDelete(LinkList L,Elemtype position)
{
	Elemtype i=1;
	LinkList p,q;
	p=L;
	while(p&&i<=position)
	{
		q=p;
		p=p->next;
		i++;
	} 
	q->next=p->next;
	free(p);
} 
//输出链表
void ListTraverse(LinkList L)
{
	LinkList p;
	p=L->next;
	while(p)
	{
		printf("%d ",p->data);
		p=p->next;
	}
} 
//用头插法输入元素
Status CreateList(LinkList L)
{
	LinkList p,q;
	q=NULL;
	Elemtype elem;
	while(1)
	{
		p=(LinkList)malloc(sizeof(LNode));
		if(!p)
		  exit(OVERFLOW);
		scanf("%d",&elem); 
		if(elem==-1)
		   break; 
		p->data=elem;
		p->next=q;
		q=p;		
	}
	L->next=q;
	return OK;
 } 
//逆置链表 
void NegaListTraverse(LinkList L)
{
	LinkList p,q;
	p=L->next;
	L->next=NULL;
	while(p)
	{		
		q=(LinkList)malloc(sizeof(LNode));
		if(!q)
		  exit(OVERFLOW);
		q->data=p->data;
		q->next=L->next;
		L->next=q;  
        p=p->next;
	}
}

OK,就到这里,谢谢观看,下次再会!
如果你发现了错误,请指正!!!

©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页