数据结构—单链表的基本操作(源代码)

#include <stdio.h>
#include <stdlib.h> 

typedef int Elemtype;
typedef struct Node{
	Elemtype data;
	struct Node *next;
}Node,*LinkList;
/*初始化链表需要修改头指针,修改头指针则必须用二级指针或一级指针的引用做参数,这里用二级指针*/
/*原因:初始化链表用到malloc函数,函数返回某个内存块的首地址。一级指针是指向内存块的, 如果用一级指针作参数,则只能通过指针修改指针所指内容,却无法修改指针的值,也就是指针所指的地址。而二级指针指向一级指针,所以可以用二级指针作参数,修改一级指针的值,使一级指针指向其他内存块,即指向malloc所申请的内存空间。*/
//创建头结点 
void create_ListHead(LinkList *pHead)	//初始化链表必须用二级指针	方便起见没有对参数进行检查 
{
	*pHead=(LinkList)malloc(sizeof(Node));
	if(NULL!=pHead)
		(*pHead)->next=NULL;
	else
		printf("开辟内存失败\n"); 
} 
//创建新结点 
LinkList get_newNode(Elemtype e)
{
	LinkList newNode=(LinkList)malloc(sizeof(Node));
	if(NULL!=newNode)
	{
		newNode->data=e;
		newNode->next=NULL;
		return newNode;
	}
	else
	{ 
		printf("开辟内存失败\n");
		return 0;
	} 
}
//头插
void push_Front(LinkList *L,Elemtype e)
{
	LinkList p;
	p=get_newNode(e);
	p->next=(*L)->next;
	(*L)->next=p; 
}
//尾插
void push_Back(LinkList *L,Elemtype e)
{
	LinkList tail; 
	tail=*L;
	while(NULL!=tail->next)		//让tail指向最后一个结点 
		tail=tail->next;
	tail->next=get_newNode(e);
}
//头删 
void pop_Front(LinkList *L)
{
	LinkList p;
	p=(*L)->next;
	if(p!=NULL) 
	{
		(*L)->next=p->next;
		free(p);
		p=NULL;		//养成释放内存后将指针赋值成空的习惯,防止其成为野指针 
		printf("OK\n"); 
	}
} 
//尾删 
void pop_Back(LinkList *L)
{
	LinkList p,q;
	p=*L;
	while(p->next!=NULL)
	{
		q=p;
		p=p->next;
	}
	free(p);
	p=NULL;
	q->next=NULL;
	printf("OK\n"); 
 } 
//指定元素删除 
void delete_List(LinkList *L,Elemtype key)
{
	LinkList p,q;
	for(p=*L;NULL!=p->next;p=p->next)
	{
		if(p->next->data==key)
		{
			q=p->next;		//因为最后要释放被删除的结点,所以先记录下来 
			p->next=q->next;
			free(q);
			q=NULL;
			printf("删除成功\n");
			return;
		}
	} 
	printf("删除失败\n"); 
}
//打印 
void print_List(LinkList *L)
{
	LinkList p;
	p=(*L)->next;
	if(p==NULL)
		printf("NULL\n");
	else
	{
		while(NULL!=p)
		{
		 	printf("%d ",p->data);
		 	p=p->next;
		}
	 	printf("\n"); 
	}
} 
//求长度 
int length_List(LinkList *L)
{
	LinkList p=(*L)->next;
	int length=0;
	while(NULL!=p)
	{
		length++;
		p=p->next;
	}
	return length;
} 
//查找 
int search_List(LinkList *L,Elemtype e)
{
	LinkList p=(*L)->next;
	int i=1;
	while(NULL!=p)
	{
		if(p->data==e)
			return i;
		else
			p=p->next;
		i++;
	}
	printf("不存在的\n");
	return 0; 
}
//整表删除 (留了头结点) 
void destory_List(LinkList *L)
{
	LinkList p,q;
	p=(*L)->next;
	while(p!=NULL)
	{
		q=p->next;
		free(p);
		p=q;
	}
	(*L)->next=NULL;
	printf("OK\n"); 
 } 
 //逆置 
void invert(LinkList L)  
{  
    LinkList p,q;  
    p=L->next;  
    L->next=NULL;  
    while(p)  
    {     
        q=p->next;            
        p->next=L->next;  
        L->next=p;
        p=q;  
    }  
} 
   
int main()
{
	LinkList L;int e,i,temp;
	while((i=getchar())!='#')		//输入#退出循环 
	{
		switch(i)
		{
			case '1':create_ListHead(&L);break; 
			case '2':printf("输入插入表尾的值\n");
					 scanf("%d",&e);
					 push_Back(&L,e);
					 break; 
			case '3':printf("输入插入表头的值\n");
					 scanf("%d",&e);
					 push_Front(&L,e);
					 break; 
			case '4':pop_Front(&L);break;
			case '5':pop_Back(&L);break; 
			case '6':print_List(&L);break; 
			case '7':printf("输入删除的值\n");
					 scanf("%d",&e);
					 delete_List(&L,e);
					 break;
			case '8':printf("长度为%d\n",length_List(&L));break; 
			case '9':printf("输入查找的值\n");
					 scanf("%d",&e);
					 temp=search_List(&L,e);
					 if(temp!=0)
					 	printf("%d在第%d个位置\n",e,temp);
					 break;
			case '0':destory_List(&L);break;
                        case 'a':invert(L);break;
                }
	}
	destory_List(&L); 
	free(L);
	L=NULL;
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/weixin_40908734/article/details/79193507