链表

1. 定义头文件

#ifndef __LINKLIST_H__
#define __LINKLIST_H__

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

typedef int datatype;
typedef struct linklistnode{
	datatype data;
	struct linklistnode *next;
}linklist;

linklist* create_linklist();
//边输入边创建
linklist* create_linklist_input();
// 头插法
int head_insert_linklist(linklist *head,datatype data);
//在给定位置之前插入,位置从0开始
int index_insert_linklist(linklist *head,datatype data,int index);
//根据序号查找
linklist* getByindex_linklist(linklist *head,int index);
//根据元素查找
linklist* getBydata_linklist(linklist *head,datatype data);

//删除给定的数据,只删除第一次出现的 
int deleteBydata_linklist(linklist *head,datatype data);
//删除给定的所有数据 
int deleteAlldata_linklist(linklist *head,datatype data);

//删除指定索引的数据 
int deleteByindex_linklist(linklist *head,int index);

//链表倒置
int reverse_linklist(linklist *head);
//链表有序插入
int sort_insert_linklist(linklist *head,datatype data);
//链表排序
int sort_linklist(linklist *head);
// 打印链表 
void show_linklist(linklist *head);

#endif

2. 方法实现

2.1 链表(带头结点)初始化

linklist *create_linklist(){
	linklist *head;
	head=(linklist *)malloc(sizeof(linklist));
	if(head == NULL){
		puts("no memory");
		return head;
	}
	head->data = -1;
	head->next = NULL;
	return head;
}

2.2 根据输入进行初始化

linklist *create_linklist_input(){
	linklist *head, *p,*q;
	int a = 0;
	head=(linklist *)malloc(sizeof(linklist));
	if(head == NULL){
		puts("no memory");
		return head;
	}
	head->next = NULL;
	q = head;
	while(1){
		puts("input the data");
		scanf("%d",&a);
		if(a != -1){
			p=(linklist *)malloc(sizeof(linklist));
			if(p == NULL){
				puts("no memory");
				return head;
			}
			p->data = a;
			p->next = NULL;
			q->next = p;
			q=q->next;

		}else{
				return head;
		}
	}
}

2.3 头插法插入数据

// 头插法
int head_insert_linklist(linklist *head,datatype data){
	linklist *p;
	if(head == NULL){
		printf(" the linklist is null");
		return -1;
	}
	p = (linklist *)malloc(sizeof(linklist));
	if(p == NULL){
		printf(" no memory");
		return -1;
	}
	p->data = data;
	p->next = head->next;
	head->next = p;
	return 0;

}

2.4 根据索引获取节点

//根据序号查找,序号从0开始
linklist *getByindex_linklist(linklist *head,int index){
	linklist *p;
	int i = -1;
	if((head == NULL) || (index < 0)){
		printf("the argv is invalid");
		return NULL;
	}
	p=head;
	while(p->next && i < index){
		i++;
		p = p->next;
	}
	if(i == index){
		return p;
	}else{
		printf(" the index more than linklist's length \n");
		return NULL;
	}

}

2.5 根据值获取节点

//根据元素查找
linklist *getBydata_linklist(linklist *head,datatype data){
	linklist *p;
	if(head == NULL){
		puts("the linklist is null");
		return NULL;
	}
	p = head->next;
	//注意这里的写法,这样写 很简洁。
	while(p && p->data != data){
		p=p->next;
	}
	return p;
}

2.6  给定位置进行插入

先获取 给定位置前面的那个节点。

如果位置为0,获取头结点。否则获取getByindex_linklist(head,index-1);

然后使用头插法插入节点

//在给定位置之前插入,位置从0开始 ,只需找到 位置之前的元素即可。

int index_insert_linklist(linklist *head,datatype data,int index){
	linklist *p,*q;
	int i = -1;
	if(index < 0){
		printf("the argv is invalid\n");
		return -1;
	}
	if(index == 0){
		p = head;
	}else{
		p = getByindex_linklist(head,index-1);
	}
	if(p == NULL){
		puts(" not find out");
	}else{
		q = (linklist *)malloc(sizeof(linklist));
		if(q == NULL){
			printf(" no memory");
			return -1;
		}
		q->data = data;
		q->next = p->next;
		p->next = q;
	}

	return 0;
}

2.7 删除指定元素的节点,只删除第一次出现的

// 删除指定元素的节点 
int deleteBydata_linklist(linklist *head,datatype data){
	linklist *p,*q;
	if(head == NULL){
		puts("the linklist is null");
		return -1;
	}
	p = head->next;
	q = head;
	//注意这里的写法,这样写 很简洁。
	while(p && p->data != data){
		q = p;
		p = p->next;
	}
	if(p == NULL){
		puts("the linklist no this data");
		return -1;
	}else{
		q->next = p->next;
		free(p);
		return 0;
	}
}

2.8 删除所有的指定元素

//删除链表中所有指定的元素
int deleteAlldata_linklist(linklist *head,datatype data){
	linklist *p,*q;
	if(head->next == NULL){
		puts("the linklist no data");
		return -1;
	}
 	p = head->next;
 	//先找到一个不是data的元素 
 	while(p && p->data == data){
	 	p = p->next;
	}
	head->next = p;
	q = p;
	while(p){
		if(p->data == data){
			q->next = p->next;
		}else{
			q = p;
		}
		p = p->next; 
	}
	return 0;
 } 

一点思考:对链表操作时,一次循环只进行一次p=p->next即可。这样不会出现当p=null,还要执行p->next;

在该次循环内对当前的节点进行相对应的操作

2.9 删除指定位置的元素

//删除指定位置的元素
int deleteByindex_linklist(linklist *head,int index){
	linklist *p,*q;
	if(index == 0){
		p = head;
	}else{
		p = getByindex_linklist(head,index-1);
	}
	//注意,这里我们没判断index,如果index-1,返回了最后一个元素是不可以的。
	if(p == NULL || p->next == NULL){
		puts("the argv is invalid");
		return -1;
	}
	//删除的节点需要 free掉,所以要单独保存一下。
	q = p->next;
	p->next = q->next;
	free(q);
	q=NULL;
	return 0;
}

2.10 链表倒置

// 链表倒置,把链表的头结点和数据节点一分为二,利用头插法的方式插入
int reverse_linklist(linklist *head){
	linklist *p,*q;
	if(head == NULL || head->next == NULL){
		puts("the linklist no data");
		return -1;
	}
	p = head->next;
	head->next = NULL;
	while(p){
		q=p->next;
		p->next = head->next;
		head->next = p;
		p=q;
	}
	return 0;
}

2.11 链表有序插入

//链表有序插入, 由小到大排序
int sort_insert_linklist(linklist *head,datatype data){
	linklist *p,*t;
	p = head;
	if((t=(linklist *)malloc(sizeof(linklist)))){
		t->data = data;		
	}else{
		puts("no memory");
		return -1;
	}
	while(p->next && p->next->data < data){	
		p = p->next;
	}
	t->next = p->next;
	p->next = t;
	return 0;

}

2.12 链表排序

//链表排序
int sort_linklist(linklist *head){
	linklist *p,*q,*r;
	p = head->next;
	head->next = NULL;
	while(p){
		q = p;
		p = p->next;

		//把元素有序插入到 前面链表中
		r = head;
		while(r->next && r->next->data < q->data){	
			r = r->next;
		}
		q->next = r->next;
		r->next = q;
	}
	return 0;
}

2.13 链表打印

void show_linklist(linklist *head){
	if(head == NULL){
		puts("the linklist is null");
		return;
	}
	while(head->next != NULL){
		head = head->next;
		printf("the valus is %d\n",head->data);
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值