带头节点的单向不循环链表

//filename:single_list.h
#ifndef _SINGLE_LIST__H
#define _SINGLE_LIST__H
#include "stdio.h"
#include "stdlib.h"
//带头节点单向不循环链表

typedef int datatype;

typedef struct slist{
	datatype dat;
	struct slist* next;
}s_node;
//不论是向第i个节点插入还是删除,都要在第(i-1)个节点上进行操作

//思路:malloc一个节点作为头节点,头节点的next指向null
s_node* slist_create(void);//创建一个单向带头节点不循环链表

//思路:定义一个指针p,从头节点开始遍历,遍历条件是p非空且跳过节点数小于i,则遍历结束时p为空或者p是第(i-1)个节点,此时插入新节点
int slist_insert_at(s_node* list,int i,datatype* dat);//向第i个节点插入dat

//思路:定义一个指针p,从头节点开始遍历,遍历条件是p非空且跳过节点数小于i,则遍历结束时p为空或者p是第(i-1)个节点,先保存(i+1)节点,再删除i节点
int slist_delete_at(s_node* list,int i,datatype* dat);//删除第i个节点,i从0开始

//思路:定义一个指针p,从头节点开始遍历,遍历条件是p->next非空且p->dat小于dat,则遍历结束时p为空或p->dat大于dat的节点,此时插入新节点
int slist_insert_order(s_node* list,datatype* dat);//按照dat大小顺序插入

//思路:定义一个指针p,从头节点开始遍历,直到p->next为空则结束遍历,插入新节点
int slist_insert_tail(s_node* list,datatype* dat);//向尾部插入

//思路:直接向头节点后面插入
int slist_insert_first(s_node* list,datatype* dat);//向首部插入

//思路:定义一个指针p_prev,从头节点开始遍历,直到p->next为空则结束遍历,p_prev是记录p->next为空的上一个节点,释放p,p_prev->next=null
int slist_delete_tail(s_node* list,datatype* out_dat);//删除尾部节点,注意头节点不会被删除

//思路:删除头节点后面的节点
int slist_delete_first(s_node* list,datatype*out_dat);//删除第0个节点

//思路:定义一个指针p,从头节点开始遍历,遍历条件是p->next非空且p->dat等于dat,则遍历结束时p为空或p->dat等于dat的节点,此时删除节点
int slist_delete(s_node* list,datatype* dat);//删除dat节点

//思路:定义一个指针p,从头节点开始遍历,num累计,遍历条件是p->next非空且p->dat等于dat,则遍历结束时p为空或p->dat等于dat的节点,此时返回num
int slist_find(s_node* list,datatype* dat);//find dat节点号

//思路:头节点的next为null则链表为空
int slist_isempty(s_node* list);//判断链表是否为空

//思路:根据节点的next遍历
void slist_show(s_node* list);//遍历显示node

//思路:根据节点的next遍历释放节点,注意释放前要保存下一个节点
void slist_destroy(s_node* list);//销毁链表

#endif
//filename:single_list.c
#include "single_list.h"


s_node* slist_create(void)
{
	s_node* plist = NULL;
	plist = malloc(sizeof(s_node));
	if(plist == NULL)
		return NULL;
	plist->next = NULL;
	return plist;
}//创建一个单向带头节点不循环链表

int slist_insert_at(s_node* list,int i,datatype* dat)
{
	if(i<0) return -1;
	
	s_node* p = list;//这里不能为list->next,否则开始时第0个插不进
	int j=0;
	while(p!= NULL && j<i)
	{
		//printf("debug %p\n",p->next);
		p=p->next;
		j++;
	}
	
	if(p==NULL) return -2;//例如只有5个节点,但是i大于5
	else   //p is (i-1) node
	{
		s_node* insert_node = slist_create();
		if(insert_node == NULL) return -3;
		
		insert_node->dat = *dat;//data
		insert_node->next = p->next;
		p->next = insert_node;
	}
	return 0;
	
}//向第i个节点插入dat

int slist_delete_at(s_node* list,int i,datatype* out_dat)
{
		if(i<0) return -1;
		s_node*p = list;
		int j=0;
		while(p!=NULL && j<i)
		{
			p=p->next;
			j++;
		}
		if(p==NULL) return -2;
		else //p is (i-1) node
		{
			s_node* del_node;
			del_node = p->next;
			if(out_dat!= NULL) *out_dat = del_node->dat;
			p->next = del_node->next;
			free(del_node);del_node=NULL;
		}
	return 0;
}//删除第i个节点,i从0开始


int slist_insert_order(s_node* list,datatype* dat)
{
		s_node * p=list;
		s_node* insert_node;
			
		while(p->next!=NULL)
		{
			if(p->next->dat > *dat)break;
			p=p->next;
		}
		
		insert_node = slist_create();
		if(insert_node == NULL) return -1;
		insert_node->dat = *dat;
		insert_node->next = p->next;
		p->next = insert_node;
		
		return 0;
}//按照dat大小顺序插入,从小到大顺序

int slist_insert_tail(s_node* list,datatype* dat)
{
	s_node *p=list;
	s_node *insert_node;
	while(p->next != NULL)
	{
			p=p->next;
	}
	
	insert_node = slist_create();
	if(insert_node == NULL) return -1;
	insert_node->dat = *dat;
	insert_node->next=p->next;
	p->next=insert_node;
	return 0;
}//向尾部插入

int slist_insert_first(s_node* list,datatype* dat)
{
	s_node *p=list;
	s_node *insert_node;
	
	insert_node = slist_create();
	if(insert_node == NULL) return -1;
	insert_node->dat = *dat;
	insert_node->next=p->next;
	p->next=insert_node;	
}//向首部插入

int slist_delete_tail(s_node* list,datatype* out_dat)
{
	s_node *p=list;
	s_node *p_prev;
	
	if(slist_isempty(p)==1) return -1;
	
	p_prev=p;
	while(p->next != NULL)
	{
		p_prev=p;
		p=p->next;
	}
	//p->next==NULL
	if(out_dat!=NULL) *out_dat = p->dat;
	free(p);
	p_prev->next=NULL;
	return 0;
}//删除尾部节点,注意头节点不会被删除

int slist_delete_first(s_node* list,datatype*out_dat)
{
	s_node*p=list;
	s_node *p_next;
	if(slist_isempty(p)==1) return -1;
	p_next = p->next->next;
	if(out_dat!=NULL) *out_dat = p->next->dat;
	free(p->next);
	p->next = p_next;
	return 0;
}//删除第0个节点

int slist_delete(s_node* list,datatype* dat)
{
	if(dat == NULL) return -1;
	
	s_node*p=list;
	s_node*p_next;
	while(p->next !=NULL)
	{
		if(p->next->dat == *dat) break;
		p=p->next;
	}		
	if(p->next == NULL) return -2;
	//p is *dat prev node
	p_next=p->next;
	p->next=p_next->next;
	free(p_next);
	return 0;
}//删除dat节点

int slist_find(s_node* list,datatype* dat)
{
	if(dat == NULL) return -1;
	int num=0;
	s_node*p=list;
	s_node*p_next;
	while(p->next !=NULL)
	{
		if(p->next->dat == *dat) break;
		num++;
		p=p->next;
	}		
	if(p->next == NULL) return -2;
	return num;
	
}//find dat节点号

int slist_isempty(s_node* list)
{
	if(list->next==NULL)return 1;
	return 0;
}//判断链表是否为空

void slist_show(s_node* list)
{
	if(slist_isempty(list)==1) return;
	s_node* p = list->next;
	for(;p!=NULL;p=p->next)
	{
		printf("%d ",p->dat);
	}
	printf("\n");
}//遍历显示node

void slist_destroy(s_node* list)
{
	s_node * p;
	s_node * p_next;
	for(p=list->next;p!=NULL;p=p_next)
	{
		p_next=p->next;
		//printf("free %d\n",p->dat);
		free(p);p=NULL;
	}
	free(list);list=NULL;//free head
}//销毁链表

//filename:main.c
#include "single_list.h"
datatype arr[10]={12,34,56,23,56,1,34,24,90,76};
datatype arr1[10]={24,34,6,23,6,1,100,51,90,0};
int main(int argc ,char*argv[])
{
	//-----------------------------------
	printf("特定位置插入、删除\r\n");
	s_node* L= slist_create();
	if(L==NULL) goto exit;
	int i,ret;
	for(i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
	{
		if((ret = slist_insert_at(L,i,&arr[i]))!=0)
		{
			printf("err:%d\n",ret);
			goto exit;
		}
	}
	slist_show(L);
	datatype dat;
	slist_delete_at(L,0,&dat);
	printf("del: %d\n",dat);
	slist_delete_at(L,3,&dat);
	printf("del: %d\n",dat);
	slist_delete_at(L,7,&dat);
	printf("del: %d\n",dat);	
	slist_show(L);
	slist_destroy(L);
	printf("\r\n");
	//-----------------------------------
	printf("按顺序插入\r\n");
	s_node* L1= slist_create();
	if(L1==NULL) goto exit;
	for(i=0;i<(sizeof(arr1)/sizeof(arr1[0]));i++)
	{
		if((ret = slist_insert_order(L1,&arr1[i]))!=0)
		{
			printf("err:%d\n",ret);
			goto exit;
		}
	}
	slist_show(L1);
	printf("\r\n");
	
	dat = 15;
	printf("尾部插入 %d \r\n",dat);
	slist_insert_tail(L1,&dat);//尾部插入
	slist_show(L1);
	printf("\r\n");
	
	dat = 33;
	printf("首部插入 %d \r\n",dat);
	slist_insert_first(L1,&dat);//0节点插入
	slist_show(L1);
	printf("\r\n");
	
	slist_delete_tail(L1,&dat);//尾部删除
	printf("尾部删除 %d \r\n",dat);
	slist_show(L1);
	printf("\r\n");
	
	slist_delete_first(L1,&dat);//0节点删除
	printf("首部删除 %d \r\n",dat);
	slist_show(L1);
	printf("\r\n");
	
	dat = 0;
	printf("删除%d \r\n",dat);
	slist_delete(L1,&dat);
	slist_show(L1);
	printf("\r\n");

	
	dat = 6;
	printf("删除%d \r\n",dat);
	slist_delete(L1,&dat);
	slist_show(L1);
	printf("\r\n");	

	dat = 100;
	printf("删除%d \r\n",dat);
	slist_delete(L1,&dat);
	slist_show(L1);
	printf("\r\n");	

	dat = 200;
	printf("删除%d \r\n",dat);
	slist_delete(L1,&dat);
	slist_show(L1);
	printf("\r\n");		
	
	int num;
	dat = 200;num=-1;
	if((num = slist_find(L1,&dat))>=0)
		printf("发现%d节点编号%d\r\n",dat,num);
	else
		printf("%d节点不在链表中\r\n",dat);
	slist_show(L1);
	printf("\r\n");	

	dat = 1;num=-1;
	if((num = slist_find(L1,&dat))>=0)
		printf("发现%d节点编号%d\r\n",dat,num);
	else
		printf("%d节点不在链表中\r\n",dat);
	slist_show(L1);
	printf("\r\n");	
	
	dat = 6;num=-1;
	if((num = slist_find(L1,&dat))>=0)
		printf("发现%d节点编号%d\r\n",dat,num);
	else
		printf("%d节点不在链表中\r\n",dat);
	slist_show(L1);
	printf("\r\n");	
	
	dat = 90;num=-1;
	if((num = slist_find(L1,&dat))>=0)
		printf("发现%d节点编号%d\r\n",dat,num);
	else
		printf("%d节点不在链表中\r\n",dat);
	slist_show(L1);
	printf("\r\n");	
	
	slist_destroy(L1);
	
exit:
	return 0;
}

带头节点的单向不循环链表_第1张图片
带头节点的单向不循环链表_第2张图片

你可能感兴趣的:(算法与数据结构)