//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;
}