数据结构C语言之链表

顺序表基本操作

#include "myhead.h"
#define SIZE 10  //优化1  用宏定义取代数组大小
typedef int datatype;

//定义一个结构体表示顺序表
struct list
{
	datatype buf[SIZE];
	int last; //标记目前数组中最后一个有效成员的下标
};

//初始化顺序表
struct list *list_init()
{
	struct list *mylist=malloc(sizeof(struct list));
	mylist->last=-1;
	return mylist;
}

//插入数据到顺序表中
int list_insert(datatype newdata,struct list *somelist)
{
	//判断顺序表是否满了
	if((somelist->last)>=(SIZE-1))
	{
		printf("顺序表满了!\n");
		return -1;
	}
	//先更新last
	(somelist->last)++;
	somelist->buf[somelist->last]=newdata;
}

//删除顺序表中是数据
/*
	情况一:要删除的数据在顺序表不存在
	情况二:要删除的数据是重复的(多个),全部删除
*/
int list_remove(datatype deldata,struct list *somelist)
{
	//定义一个标志位,标记是否存在要删除的数据
	int flag=0;
	//判断顺序表是否空了
	if(somelist->last==-1)
	{
		printf("顺序表空了!\n");
		return -1;
	}
	//找到要删除的数据
	int i,j;
	for(i=0; i<=somelist->last; i++)
	{
		if(somelist->buf[i]==deldata)
		{
			flag=1;
			//后面的数据往前挪动
			for(j=i; j<=somelist->last-1; j++)  
			{
				somelist->buf[j]=somelist->buf[j+1];
			}
			//更新last
			somelist->last--;	
			i--;  //注意i--是为了防止漏掉重复元素
		}
		
	}
	//判断要删除的数据不存在这种情况
	if(flag==0)
	{
		printf("对不起,没有你要删除的数据!\n");
		return -1;
	}
	
}
//修改数据
/*
	情况一:要修改的数据在顺序表不存在
	
*/
int list_update(int newdata,int olddata,struct list *somelist)
{
	int i;
	//寻找要的修改的数据olddata
	for(i=0; i<=somelist->last; i++)
	{
		if(somelist->buf[i]==olddata)
			somelist->buf[i]=newdata;
	}
}

//打印
int list_show(struct list *somelist)
{
	int i;
	for(i=0; i<=somelist->last; i++)
		printf("当前顺序表中数据是:%d\n",somelist->buf[i]);
}

int main()
{
	int n;
	int i;
	//初始化顺序表
	struct list *mylist=list_init();
	//插入数据
	for(i=0; i<4; i++)
	{
		printf("请输入要插入的整数!\n");
		scanf("%d",&n);
		list_insert(n,mylist);
	}
	//打印
	printf("=======插入完毕======\n");
	list_show(mylist);
	
	//删除
	list_remove(55,mylist);
	//打印
	printf("=======删除完毕======\n");
	list_show(mylist);
	
	//修改数据
	//list_update(99,88,mylist);
	//打印
	//printf("=======修改完毕======\n");
	//list_show(mylist);
	
}

单链表基本操作

#include "myhead.h"
//定义结构体表示单链表
struct siglelist
{
	int data;
	struct siglelist *next;
};

//封装链表的初始化
struct siglelist *list_init()
{
	struct siglelist *myhead=malloc(sizeof(struct siglelist));
	myhead->next=NULL;
	return myhead;
}

//尾部插入
int insert_tail(int newdata,struct siglelist *head)
{
	//找到链表的尾部
	struct siglelist *p=head;
	while(p->next!=NULL)
		p=p->next; //把赋值=  翻译成指向
	//准备好新的节点
	struct siglelist *newnode=malloc(sizeof(struct siglelist));
	newnode->data=newdata;
	newnode->next=NULL;
	
	//p的下一个节点指向newnode
	p->next=newnode;
}

//中间插入,把newdata插入到olddata的后面
int insert_mid(int newdata,int olddata,struct siglelist *head)
{
	//找到olddata所在的节点
	struct siglelist *p=head;
	while(p->next!=NULL)
	{
		p=p->next;
		if(p->data==olddata)
			break;
	}
	//准备新节点
	struct siglelist *newnode=malloc(sizeof(struct siglelist));
	newnode->data=newdata;
	newnode->next=NULL;
	
	newnode->next=p->next;
	p->next=newnode;
}

//单链表的删除,用两个指针解决
int remove_list(int deldata,struct siglelist *head)
{
	int flag=0; //标记是否找到要删除的数据
	//找到要删除的节点
	struct siglelist *q=head;
	struct siglelist *p=head->next;
	while(p->next!=NULL)
	{
		if(p->data==deldata)
		{
			flag=1;
			q->next=p->next;
			p->next=NULL;
			free(p);
			p=q->next;
		}	
		else
		{
			p=p->next;
			q=q->next;
		}
	}
	//经过仔细分析,发现前面的循环漏掉了最后一个数据没有判断,没有删除
	if(p->next==NULL && p->data==deldata)
	{
		//把最后一个数据删除即可
		q->next=NULL;
		free(p);
		p=NULL;
		return 0;
	}
	if(flag==0 && p->next==NULL && p->data!=deldata)
	{
		printf("没有你要删除的数据!\n");
		return -1;
	}
}
//打印链表
int show_list(struct siglelist *head)
{
	struct siglelist *p=head;
	while(p->next!=NULL)
	{
		p=p->next;
		printf("当前遍历的节点中存放的数据是:%d\n",p->data);
	}
}
int main()
{
	int m,n;
	int i;
	//准备头节点
	struct siglelist *mylist=list_init();
	//尾插一部分数据
	for(i=0; i<4; i++)
	{
		printf("输入尾插数据!\n");
		scanf("%d",&m);
		insert_tail(m,mylist);
	}
	
	//打印 
	printf("=====尾部插入========\n");
	show_list(mylist);
	
	//删除数据
	printf("请输入你要删除的数据!\n");
	scanf("%d",&n);
	remove_list(n,mylist);
	printf("=====删除完毕========\n");
	show_list(mylist);
	
	
}

单向循环链表基本操作

#include "myhead.h"
//定义结构体表示单向循环链表
struct siglelist
{
	int data;
	char name[10];
	double weight; //前面三个都是属于数据域里面的数据成员
	struct siglelist *next; //指针域
};

//封装链表的初始化
struct siglelist *list_init()
{
	struct siglelist *myhead=malloc(sizeof(struct siglelist));
	myhead->next=myhead;
	return myhead;
}

//尾部插入
int insert_tail(int newdata,char *newname,double newweight,struct siglelist *head)
{
	//找到链表的尾部
	struct siglelist *p=head;
	while(p->next!=head)
		p=p->next; //把赋值=  翻译成指向
	//准备好新的节点
	struct siglelist *newnode=malloc(sizeof(struct siglelist));
	newnode->data=newdata;
	strcpy(newnode->name,newname);
	newnode->weight=newweight;
	newnode->next=NULL;
	
	//p的下一个节点指向newnode
	p->next=newnode;
	newnode->next=head;
}

//中间插入,把newdata插入到olddata的后面
int insert_mid(int newdata,int olddata,struct siglelist *head)
{
	//找到olddata所在的节点
	struct siglelist *p=head;
	while(p->next!=head)
	{
		p=p->next;
		if(p->data==olddata)
			break;
	}
	//准备新节点
	struct siglelist *newnode=malloc(sizeof(struct siglelist));
	newnode->data=newdata;
	strcpy(newnode->name,"赵六");
	newnode->weight=70.5;
	newnode->next=NULL;
	
	newnode->next=p->next;
	p->next=newnode;
}

//单链表的删除,用两个指针解决
int remove_list(int deldata,struct siglelist *head)
{
	int flag=0; //标记是否找到要删除的数据
	//找到要删除的节点
	struct siglelist *q=head;
	struct siglelist *p=head->next;
	while(p->next!=head)
	{
		if(p->data==deldata)
		{
			flag=1;
			q->next=p->next;
			p->next=NULL;
			free(p);
			p=q->next;
		}	
		else
		{
			p=p->next;
			q=q->next;
		}
	}
	//经过仔细分析,发现前面的循环漏掉了最后一个数据没有判断,没有删除
	if(p->next==NULL && p->data==deldata)
	{
		//把最后一个数据删除即可
		q->next=NULL;
		free(p);
		p=NULL;
		return 0;
	}
	if(flag==0 && p->next==NULL && p->data!=deldata)
	{
		printf("没有你要删除的数据!\n");
		return -1;
	}
}
//打印链表
int show_list(struct siglelist *head)
{
	struct siglelist *p=head;
	while(p->next!=head)
	{
		p=p->next;
		printf("当前遍历的节点中存放的数据是:%d\n",p->data);
		printf("当前遍历的节点中存放的数据名字是:%s\n",p->name);
		printf("当前遍历的节点中存放的数据体重是:%lf\n",p->weight);
	}
}
int main()
{
	int m,n;
	char newname[10];
	double newweight;
	int i;
	//准备头节点
	struct siglelist *mylist=list_init();
	//尾插一部分数据
	for(i=0; i<3; i++)
	{
		printf("输入尾插数据!\n");
		scanf("%d",&m);
		printf("输入尾插数据名字!\n");
		scanf("%s",newname);
		printf("输入尾插数据体重!\n");
		scanf("%lf",&newweight);
		insert_tail(m,newname,newweight,mylist);
	}
	
	//打印 
	printf("=====尾部插入========\n");
	show_list(mylist);
	
	//中间插入
	//insert_mid(23,55,mylist);
	//打印 
	//printf("=====中间插入========\n");
	//show_list(mylist);
	
	//删除数据
	remove_list(1,mylist);
	printf("=====删除完毕========\n");
	show_list(mylist); 
	
	
}

普通双向链表

#include "myhead.h"

//定义一个结构体表示双向链表
typedef struct doublelist
{
	int data;
	struct doublelist *next;
	struct doublelist *prev;
}dlist;

//初始化双向链表的表头

dlist *init_list()
{
	dlist *head=malloc(sizeof(dlist));
	head->next=NULL;
	head->prev=NULL;
	return head;
}

//尾插
int insert_tail(int newdata,dlist *head)
{
	//找到尾部
	dlist *p=head;
	while(p->next!=NULL)
		p=p->next;
	
	//准备新的节点
	dlist *newnode=malloc(sizeof(dlist));
	newnode->data=newdata;
	newnode->next=NULL;
	newnode->prev=NULL;
	
	//尾插
	p->next=newnode;
	newnode->prev=p;
}

//遍历打印
int show_list(dlist *head)
{
	//找到尾部
	dlist *p=head;
	while(p->next!=NULL)
	{
		p=p->next;
		printf("当前遍历的节点中存放的数据是:%d\n",p->data);
	}
		
}

//中间插入
int insert_mid(int newdata,int olddata,dlist *head)
{
	//找到老的数据
	dlist *p=head;
	while(p!=NULL) //循环退出的时候p到了最后一个节点的后面位置--》NULL
	{
		if(p->data==olddata)
			break;
		p=p->next;
	}
	//插入新的数据到olddata的后面
	//准备新的节点
	dlist *newnode=malloc(sizeof(dlist));
	newnode->data=newdata;
	newnode->next=NULL;
	newnode->prev=NULL;
	
	//仔细分析发现,最后一个节点的后面插入,写法跟下面的写法不一样
	if(p->next==NULL)
	{
		p->next=newnode;
		newnode->prev=p;
		return 0;
	}
	else
	{
		//插入新的数据到olddata的后面
		newnode->next=p->next;
		p->next=newnode;
		newnode->next->prev=newnode;
		newnode->prev=p;
		return 0;
	}
	
		
}
int main()
{
	//准备一个双向链表
	dlist *myhead=init_list();
	
	//尾插几个数据
	insert_tail(78,myhead);
	insert_tail(478,myhead);
	insert_tail(5478,myhead);
	insert_tail(58,myhead);
	insert_tail(28,myhead);
	
	//打印
	printf("====尾插完毕=====\n");
	show_list(myhead);
	
	//中间插入
	//insert_mid(999,78,myhead);
	insert_mid(999,28,myhead);
	//打印
	printf("====中间插入完毕=====\n");
	show_list(myhead);
}
上一篇:js进阶 11-6 jquery如何获取和设置元素的宽高(jquery多方法)


下一篇:数据结构--双向链表的实现(复习)