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