单向链表的C语言实现
singlelinketlist.h
#ifndef SINGLE_LINKET_LIST_H__
#define SINGLE_LINKET_LIST_H__
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
//单向链表结点
typedef int ETYPE;
//单向链表结点类型
typedef struct Node{
ETYPE elem; //元素
struct Node *next; //下一个节点的位置
}SNode,*SLinketList;
#define NODESIZE sizeof(struct Node)
SLinketList slinket_list_create(void);
//判断单向链表是否为空
bool slinket_list_is_empty(SLinketList head);
//单向链表中元素的个数
size_t slinket_list_size(SLinketList head);
//在指定位置pos插入一个元素elem 第一个位置默认为0
int slinket_list_insert(SLinketList head,size_t pos,ETYPE elem);
//在单向链表前面插入一个元素elem
int slinket_list_insert_front(SLinketList head,ETYPE elem);
//在单向链表末尾插入一个元素elem
int slinket_list_insert_back(SLinketList head,ETYPE elem);
//删除指定位置pos的元素
int slinket_list_delete(SLinketList head,size_t pos,ETYPE *pelem);
//删除单向链表第一个元素
int slinket_list_delete_front(SLinketList head,ETYPE *pelem);
//删除末尾的元素
int slinket_list_delete_back(SLinketList head,ETYPE *pelem);
//获取指定位置pos的元素
int slinket_list_get(SLinketList head,size_t pos,ETYPE *pelem);
//获取第一个元素
int slinket_list_get_front(SLinketList head,ETYPE *pelem);
//获取最后一个元素
int slinket_list_get_back(SLinketList head,ETYPE *pelem);
//根据值key来查找 返回-1表示没有该值 否则返回位置
int slinket_list_find(SLinketList head,ETYPE *pelem);
//遍历单向链表
void slinket_list_travel(SLinketList head,void (*travel)(int));
//删除所有元素 清空所有元素
void slinket_list_clear(SLinketList head);
//销毁单向链表
void slinket_list_destroy(SLinketList head);
//单向链表逆序
void slinket_list_reverse(SLinketList head);
//获取倒数第n个元素
int slinket_list_get_last(SLinketList head,size_t pos,ETYPE *pelem);//[1,...
// a1,a2,a3... an-1,an a1,an,a2,an-1,a3,an-2,...
void slinket_list_reset_seq(SLinketList head);
// 按指定元素个数逆序 a1,a2,a3,a4,a5,a6,a7,a8 a3,a2,a1,a6,a5,a4,a8,a7
void slinket_list_reverse_by_count(SLinketList head,size_t count);
#endif //SINGLE_LINKET_LIST_H__
singlelinketlist.c
#include "singlelinketlist.h"
SLinketList slinket_list_create(void){
struct Node* head = (struct Node*)malloc(NODESIZE);//头结点
if(head==NULL){
return NULL;
}
head->next = NULL;
return head;
}
//判断单向链表是否为空
bool slinket_list_is_empty(SLinketList head){//head 指针 指向头结点 *head头结点
return head->next == NULL; //(*head).next == NULL
}
//单向链表中元素的个数
size_t slinket_list_size(SLinketList head){
size_t size = 0;
struct Node *node = head->next;//head指向头结点 head->next指向第一个结点
while(node != NULL){
size++;
node = node->next;//让node指针指向下一个节点
}
return size;
}
//获取pos位置的前一个结点 如果pos过大,返回NULL
static struct Node * slinket_list_get_prev_node(SLinketList head,size_t pos){
struct Node *node = head;
size_t i;
for(i=0;node!=NULL&&i<pos;i++){
node = node->next;
}
return node;
}
//在指定位置pos插入一个元素elem 第一个位置默认为0
int slinket_list_insert(SLinketList head,size_t pos,ETYPE elem){ //要获取pos-1节点的指针 pos==0 头结点
struct Node *prev = slinket_list_get_prev_node(head,pos);
if(prev == NULL){
return -1;
}
struct Node *node = (struct Node *)malloc(NODESIZE);
if(node==NULL){
return -2;
}
node->elem = elem;
node->next = prev->next;
prev->next = node;
return 0;
}
//在单向链表前面插入一个元素elem
int slinket_list_insert_front(SLinketList head,ETYPE elem){
struct Node *node = (struct Node *)malloc(NODESIZE);
if(node==NULL){
return -1;
}
node->elem = elem;
node->next = head->next;
head->next = node;
return 0;
}
//在单向链表末尾插入一个元素elem
int slinket_list_insert_back(SLinketList head,ETYPE elem){
//size_t size = slinket_list_size(head);
//return slinket_list_insert(head,sie,elem);
struct Node *last = head;
while(last->next!=NULL){
last = last->next;
}
//last->next == NULL
//last->next = (struct Node *)malloc(NODESIZE);
//last->next->elem = elem;
//last->next->next = NULL;
struct Node *node = (struct Node *)malloc(NODESIZE);
node->elem = elem;
node->next = NULL;
last->next = node;
return 0;
}
//删除指定位置pos的元素
int slinket_list_delete(SLinketList head,size_t pos,ETYPE *pelem){
struct Node *prev = slinket_list_get_prev_node(head,pos);
if(prev == NULL || prev->next == NULL){
return -1;
}
struct Node *curr = prev->next;
prev->next = curr->next;
*pelem = curr->elem;
free(curr);
return 0;
}
//删除单向链表第一个元素
int slinket_list_delete_front(SLinketList head,ETYPE *pelem){
if(head->next == NULL){
return -1;
}
*pelem = head->next->elem;
struct Node *first = head->next;
head->next = first->next;
free(first);
return 0;
}
//删除末尾的元素
int slinket_list_delete_back(SLinketList head,ETYPE *pelem){
if(head->next == NULL){
return -1;
}
//size_t size = slinket_list_size(head);
//return slinket_lsit_delete(head,size-1,pelem);
struct Node *lastSec = head;
while(lastSec->next->next != NULL){
lastSec = lastSec->next;
}
//lastSec记录的是倒数第二个结点
*pelem = lastSec->next->elem;
free(lastSec->next);//释放最后一个结点的内存
lastSec->next = NULL;
return 0;
}
//获取指定位置pos的元素
int slinket_list_get(SLinketList head,size_t pos,ETYPE *pelem){
struct Node *node = slinket_list_get_prev_node(head,pos+1);
if(node == NULL){
return -1;
}
*pelem = node->elem;
return 0;
}
//获取第一个元素
int slinket_list_get_front(SLinketList head,ETYPE *pelem){
if(head->next == NULL){
return -1;
}
*pelem = head->next->elem;
return 0;
}
//获取最后一个元素
int slinket_list_get_back(SLinketList head,ETYPE *pelem){
if(head->next == NULL){
return -1;
}
struct Node *last = head->next;
while(last->next != NULL){
last = last->next;
}
*pelem = last->elem;
return 0;
}
//根据值key来查找 返回-1表示没有该值 否则返回位置
int slinket_list_find(SLinketList head,ETYPE *pelem){
struct Node *node = head->next;
size_t i;
for(i=0;node!=NULL;node=node->next,i++){
if(node->elem == *pelem){
return i;
}
}
return -1;
}
//遍历单向链表
void slinket_list_travel(SLinketList head,void (*travel)(int)){
struct Node *node = head->next;
while(node!=NULL){
travel(node->elem);
node = node->next;
}
}
//删除所有元素 清空所有元素
void slinket_list_clear(SLinketList head){
struct Node *node,*next;
for(node=head->next;node!=NULL;node=next){
next = node->next;//提前保存node后面一个节点的位置
free(node);//释放node所指向的结点内存
}
head->next = NULL;
}
//销毁单向链表
void slinket_list_destroy(SLinketList head){
slinket_list_clear(head);
free(head);//释放头结点的内存空间
}
//单向链表逆序
void slinket_list_reverse(SLinketList head){
//没有结点 或者 只有一个结点 不需要做任何事情
if(head->next == NULL || head->next->next == NULL){
return;
}
struct Node *prev = NULL;
struct Node *curr = head->next;
struct Node *next = NULL;
while(curr!=NULL){
next = curr->next; //保存当前结点的下一个结点的位置
curr->next = prev; //逆转当前curr结点 指向原来的前结点
prev = curr;
curr = next;
}
head->next = prev;
}
//获取倒数第n个元素
int slinket_list_get_last(SLinketList head,size_t pos,ETYPE *pelem){
struct Node *front = head->next;
struct Node *back = head->next;
size_t i;
for(i=1;front!=NULL&&i<pos;i++){
front = front->next;//先让front先走pos-1步
}
if(front == NULL){
return -1;
}
while(front->next!=NULL){
front = front->next;
back = back->next;
}
//front指向最后一个 back指向前面 pos-1
*pelem = back->elem;
return 0;
}
// a1,a2,a3... an-1,an a1,an,a2,an-1,a3,an-2,...
// 1 2 3 4 5 6 7 8 9 10 1 10 2 9 3 8 4 7 5 6
void slinket_list_reset_seq(SLinketList head){
size_t size = slinket_list_size(head);
if(size<=2)
return;
size_t i;
struct Node *node = head->next;
for(i=0;i<size/2;i++){
node = node->next;
}
//node 作为头结点一样使用
slinket_list_reverse(node);
struct Node *front = node->next, *back = head->next;
node->next = NULL;
node = head;
bool flag = true;
while(front!=NULL && back!=NULL){
node->next = back;
back = back->next;
node = node->next;
node->next = front;
front = front->next;
node = node->next;
xt = back;
}
void slinket_list_reverse_by_count(SLinketList head,size_t count){
struct Node *prev = NULL;
struct Node *curr = head->next;
struct Node *next = NULL;
struct Node *last = head;//上次逆转之后的最后一个结点
struct Node *first = NULL;
size_t i=0;
while(curr != NULL){
first = curr;//记录该次逆序的第一个结点
for(i=0;curr!=NULL&&i<count;i++){
next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
last->next = prev;//上次逆转之后最后一个结点的下一个结点应该
last = first;
}
last->next = NULL;
}