Slink.h
#ifndef _SLINK_H__
#define _SLINK_H__
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef int T;
//单向链表的节点
typedef struct SNode{
T data; //节点元素
struct SNode *next; //下一个节点的地址 指向下一个节点
}SNode;
//定义单向链表类型 SLink
typedef struct SNode * SLink;
void init(SLink* plink);//plink是一个二级指针
SLink createSLink();
bool isEmpty(SLink link);
void insertFront(SLink link,T data);
void insertBack(SLink link,T data);
void travel(SLink link);
size_t size(SLink link);
void insert(SLink link,size_t index,T data);
void deleteByIndex(SLink link,size_t index);
void deleteData(SLink link,T data);
void deleteAllDatas(SLink link,T data);
void clear(SLink link);
void destroy(SLink* plink);
void modify(SLink link,size_t index,T data);
T getDataByIndex(SLink link,size_t index);
void reverse(SLink link);
#endif //_SLINK_H__
Slink.c
#include “slink.h”
void init(SLink* plink){
*plink = malloc(sizeof(SNode));
(*plink)->next = NULL;
}
SLink createSLink(){
SNode * node = malloc(sizeof(SNode));
node->next = NULL;
return node;
}
bool isEmpty(SLink link){
return link->next == NULL;
}
void insertFront(SLink link,T data){
SNode *node = malloc(sizeof(SNode));
node->data = data;
node->next = link->next;
link->next = node;
}
void travel(SLink link){
if(link != NULL){
SNode *node = link->next;
while(node != NULL){
printf("%d ",node->data);
node = node->next;
}
printf("\n");
}
}
size_t size(SLink link){
SNode *node = link->next;
size_t cnt = 0;
while(node != NULL){
cnt++;
node = node->next;
}
return cnt;
}
//获得index下标位置节点的前一个节点
static SNode *getPrevNode(SLink link,size_t index){
SNode *node = link;
for(int i=0;i<index;i++){
node = node->next;
}
return node;
}
//在指定的下标位置插入一个元素
void insert(SLink link,size_t index,T data){
if(index>size(link)){
return;
}
//找到index下标节点的前一个节点
SNode *prevNode = getPrevNode(link,index);
SNode *currNode = malloc(sizeof(SNode));
currNode->data = data;
currNode->next = prevNode->next;
prevNode->next = currNode;
}
void deleteByIndex(SLink link,size_t index){
if(index>=size(link)){
return;
}
SNode *prevNode = getPrevNode(link,index);
SNode *currNode = prevNode->next;
prevNode->next = prevNode->next->next;
free(currNode);//释放内存
}
//清空链表中的元素
void clear(SLink link){
SNode *node = link->next;
while(node != NULL){
SNode *next = node->next;//记录当前节点的后一个节点位置
free(node);//释放当前节点的内存
node = next;//指向下一个节点
}
link->next = NULL;
}
void destroy(SLink *plink){
clear(*plink);
free(*plink);
*plink = NULL;
}
void deleteData(SLink link,T data){
SNode *prevNode = link;
SNode *currNode = link->next;
while(currNode != NULL){
if(currNode->data == data){
prevNode->next = currNode->next;
free(currNode);
return;
}
prevNode = currNode;
currNode = currNode->next;
}
}
void deleteAllDatas(SLink link,T data){
SNode *prevNode = link;//头节点
SNode *currNode = link->next;
while(currNode != NULL){
if(currNode->data == data){
prevNode->next = currNode->next;
free(currNode);
currNode = prevNode->next;
continue;
}
prevNode = currNode;
currNode = currNode->next;
}
}
void modify(SLink link,size_t index,T data){
if(index>=size(link)){
return;
}
SNode *node = getPrevNode(link,index+1);
node->data = data;
}
//如果index>=size(link)都将引发错误
T getDataByIndex(SLink link,size_t index){
/*
if(index>=size(link)){
return -1;
}
*/
SNode *node = link->next;
for(int i=0;i<index;i++){
node = node->next;
}
return node->data;
}
//笔试题概率最大的编程题
void reverse(SLink link){
//if(link==NULL){return;}
//没有节点或者只有一个节点时 不需要做任何事情
if(link->next == NULL || link->next->next == NULL){
return;
}
SNode *prevNode = link->next;//第一个节点 前面节点
SNode *currNode = prevNode->next;//第二个节点
while(currNode != NULL){
SNode *nextNode = currNode->next;//记录当前节点的后一个节点
currNode->next = prevNode;//让当前节点的next指向之前的前节点
prevNode = currNode;//前节点变 指向现在当前的节点
currNode = nextNode;//当前的节点 指向 下一个节点
}
link->next->next = NULL;//让原来的第一个节点的next指向NULL
link->next = prevNode;//让头节点next指向原来最后的那个节点
}
//头节点 不保存数据
int main(){
SLink link = createSLink();
//init(&link);
if(isEmpty(link)){
printf("链表为空!\n");
}else{
printf("非空!\n");
}
insertFront(link,1);
insertFront(link,2);
insertFront(link,3);
insertFront(link,2);
insertFront(link,1);
travel(link);
printf("%u\n",size(link));
insert(link,5,100);
insert(link,6,200);
insert(link,2,30);
insert(link,4,40);
travel(link);//1 2 30 3 40 2 1 100 200
reverse(link);
travel(link);
printf("%u\n",size(link));
deleteByIndex(link,8);
deleteByIndex(link,3);
printf("%u\n",size(link));
travel(link);
deleteData(link,100);
deleteData(link,30);
insert(link,1,2);
travel(link);
deleteAllDatas(link,2);
travel(link);
destroy(&link);
return 0;
}