算法与数据结构-线性表

269 阅读6分钟

1. 线性表

顺序存储表

代码实践

  • 声明文件(h文件 )
 #ifndef List_h
#define List_h

#include <stdio.h>

typedef struct List{
   int count;    // 当初线性表长度
   int capacity; // 线性表容量
   void **data;  // 线性表存储的元素数组
} List;

//初始化数组
List *listInit(void);
/**
释放数组
@param list 数组结构体指针
*/
void listFree(List *list);
/*
向列表里添加元素
@param list  数组结构体指针
@param value 添加的值
*/
void listAppend(List *list,void *value);
/**
打印线性表的数据元素
@param list          数组结构体指针
@param function 打印函数指针
*/
void listPrintf(List *list, void (*function)(void *value));
/**
获取value值通过下标
@param list   数组结构体指针
@param index 获取值的下标位置
*/
void* listGetValueOfIndex(List *list,int index);
/**
插入数据
@param list   数组结构体指针
@param index 插入值的下标位置
*/
void listInsertValueOfIndex(List *list, void* value , int index);
#endif /* List_h */
  • 实现文件(c文件)
#include "List.h"
#include <stdlib.h>
#include <assert.h>
#define CapacityIncrement 10
//初始化数组
List *listInit(void){
   List *list = NULL;
   list = (List *)malloc(sizeof(List));
   list->data = malloc( sizeof(void)*CapacityIncrement);
   list->capacity = CapacityIncrement;
   list->count = 0;
   return list;
}
void allocCapacity(List *list);
//向列表里添加元素
void listAppend(List *list,void *value){
   assert(value != NULL && list != NULL);
   allocCapacity(list);
   list->data[list->count] = value;
   list->count += 1;
}
/*
检测内存不足则分配内存空间
**/
void allocCapacity(List *list){
   if (list->count >= list->capacity) {
       void** newspace = malloc(sizeof(void*)*(list->capacity + CapacityIncrement));
       memcpy(newspace, list->data, list->capacity*sizeof(void*));
       free(list->data);
       list->data = newspace;
       list->capacity = list->capacity+CapacityIncrement;
   }
}

void listPrintf(List *list, void (*function)(void *value)){
   for (int i = 0; i < list->count; i++) {
       void *value = list->data[i];
       function(value);
   }
}
void* listGetValueOfIndex(List *list , int index){
   assert(list != NULL);
   assert(index>=0 && index < list->count);
   return list->data[index];
}

void listInsertValueOfIndex(List *list, void* value , int index){
   assert(list != NULL);
   assert(index>=0 && index <= list->count);
   allocCapacity(list);
   
   //将index开始的每个元素后移
   for (int i = list->count-1; i >= index; i--) {
       list->data[i+1] = list->data[i];
   }
   list->data[index] = value;
   list->count += 1;
}

void listFree(List *list){
   if (list->data != NULL) {
       free(list->data);
   }
   if (list != NULL) {
       free(list);
   }
}

链式存储表

代码实践

  • 声明文件(h文件 )
#ifndef Link_h
#define Link_h

#include <stdio.h>

typedef struct LinkNode{
   void* data;
   struct LinkNode* next;
} LinkNode;

typedef struct Link{
   int count;
   LinkNode *last;  //链表的最后一个节点
   LinkNode *first; //链表的第一个节点
} Link;

/**
链表初始化
*/
Link* linkInit(void);
/**
向链表中添加值
@param link   链表结构体变量指针
@param value 添加的值
*/
void linkAppend(Link *link, void *value);
/**
移除链表中的值
@param link   链表结构体变量指针
@param index 添加的值
*/
void linkRemoveOfIndex(Link *link, int index);
/**
向链表中插入值
@param link   链表结构体变量指针
@param value 插入的值
@param index 插入的位置
*/
void linkInsertValueOfIndex(Link *link,void* value, int index);

/**
获取链表中的值
@return void* 无类型指针
@param link   链表结构体变量指针
@param index 获取的值的位置
*/
void* linkGetValueOfIndex(Link *link, int index);
/**
打印链表中的值
@param link   链表结构体变量指针
@param function 需要自定义打印的函数指针
*/
void linkPrintf(Link *link, void(*function)(void *));
/**
释放链表
*/
void linkFree(Link *link);


#endif /* Link_h */

  • 实现文件(m文件 )
#include "Link.h"
#include <stdlib.h>
#include <assert.h>
/**
链表初始化
*/
Link* linkInit(void){
   Link *link = (Link*)malloc(sizeof(Link));
   link->first = NULL;
   link->count = 0;
   link->last = link->first;
   return link;
}
/**
向链表中添加值
@param link   链表结构体变量指针
@param value 添加的值
*/
void linkAppend(Link *link, void *value){
   assert(link != NULL);
   LinkNode *node = (LinkNode *)malloc(sizeof(LinkNode));
   node->data = value;
   node->next = NULL;
   
   if (link->first == NULL) {//如果头结点为NULL说明链表里面没有值
       link->first = node;
       link->last = link->first;
   }else{
       link->last->next = node;
       link->last = node;
   }
   link->count += 1;
}
/**
移除链表中的值
@param link   链表结构体变量指针
@param index 添加的值
*/
void linkRemoveOfIndex(Link *link, int index){
   assert(link != NULL);
   if (link->first == NULL) {//空链表
       return;
   }
   assert(index >= 0 && index < link->count);
   //找出需要删除的节点的前一个节点
   LinkNode *node = NULL;
   for (int i = 0; i < index; i++) {
       if (i != 0) {
           node = node->next;
       }else{
           node = link->first;
       }
   }
   
   LinkNode *deleteNode = NULL;
   if (node == NULL) {//如果node为NULL则说明需要删除的是头节点
       deleteNode = link->first;
       link->first = deleteNode->next;
   }else{
       deleteNode = node->next;
       node->next = deleteNode->next;
   }
   //如果被删除的节点的 next == NULL 说明删除的是尾节点
   if (deleteNode->next == NULL) {
       link->last = node;
   }
   link->count -= 1;
   free(deleteNode);
}
/**
向链表中插入值
@param link   链表结构体变量指针
@param value 插入的值
@param index 插入的位置
*/
void linkInsertValueOfIndex(Link *link,void* value, int index){
   assert(link != NULL);
   assert(index >= 0 && index <= link->count);
   
   //如果链表是空或者是插入在链表的尾部则直接调用添加方法
   if (link->first == NULL || index == link->count) {
       linkAppend(link, value);
       return;
   }
   
   LinkNode *frontNode = NULL ;
   for (int i = 0; i < index; i++) {
       if (i != 0) {
           frontNode = frontNode->next;
       }else{
           frontNode = link->first;
       }
   }
   
   LinkNode *node = (LinkNode *)malloc(sizeof(LinkNode));
   node->data = value;
   node->next = NULL;
   
   LinkNode *nextNodel = NULL;
   if (frontNode == NULL) {
       nextNodel = link->first;
       link->first = node;
       node->next = nextNodel;
   }else{
       nextNodel = frontNode->next;
       node->next = nextNodel;
       frontNode->next = node;
   }
   link->count += 1;
}
/**
获取链表中的值
@return void* 无类型指针
@param link   链表结构体变量指针
@param index 获取的值的位置
*/
void* linkGetValueOfIndex(Link *link, int index){
   assert(link != NULL);
   assert(index >= 0 && index < link->count);

   LinkNode *node = NULL;
   for (int i = 0; i <= index; i++) {
       if (i != 0) {
           node = node->next;
       }else{
           node = link->first;
       }
   }
   return node->data;
}
/**
打印链表中的值
@param link   链表结构体变量指针
@param function 需要自定义打印的函数指针
*/
void linkPrintf(Link *link, void(*function)(void *)){
   assert(link != NULL);
   LinkNode *nextLink = NULL;
   for (int i = 0; i < link->count; i++) {
       if (i == 0) {
           nextLink = link->first;
       }else{
           nextLink = nextLink->next;
       }
       function(nextLink->data);
   }
}
/**
释放链表
*/
void linkFree(Link *link){
   if (link != NULL) {
       for (int i = 0; i < link->count; i++) {
           LinkNode *node = link->first;
           LinkNode *nextNode = node->next;
           link->first = nextNode;
           free(node);
       }
   }
   if (link->last != NULL) {
       free(link->last);
   }
   free(link);
}

企业级链表

代码实践

  • 声明文件(h文件 )
#ifndef EnterpriseLink_h
#define EnterpriseLink_h

#include <stdio.h>

typedef struct ENode {
   struct ENode *nextNode;//下一个节点
} ENode;

typedef struct ELink{
   ENode head;  //头节点
   int   count; //节点数据量
}ELink;

//相当于ENode的一个可以附带参数的副本
typedef struct ExtENode{
   //nextNodel的位置不能改变,因为当ExtENode*类型转换成ENode*将找不到nextNode
   ENode *nextNode;
   int data;
} ExtENode;

/**
初始化链表
*/
ELink *eLinkInit(void);

/**
向链表里添加值
@param eLink 链表
@param value 添加的值
*/
void eLinkAppendValue(ELink *eLink,ENode *value);

/**
向链表里插入值
@param eLink 链表
@param value 添加的值
@param index 插入的位置
*/
void eLinkInsertValueOfIndex(ELink *eLink,ENode *value,int index);

/**
移除链表里的值
@param eLink 链表
@param index 移除的位置
*/
void eLinkRemoveOfIndex(ELink *eLink,int index);

/**
打印链表
*/
void eLinkPrintf(ELink *eLink, void (*founction)(ENode *eNode));

/*
释放链表
@param eLink 链表
**/
void eLinkFree(ELink *eLink);

#endif /* EnterpriseLink_h */


  • 实现文件(m文件 )
#include <stdlib.h>
#include <assert.h>
#include "EnterpriseLink.h"
/**
初始化链表
*/
ELink *eLinkInit(void){
   ELink *eLink = (ELink*)malloc(sizeof(ELink));
   eLink->head.nextNode = NULL;
   eLink->count = 0;
   return eLink;;
}

/**
向链表里添加值
@param eLink 链表
@param value 添加的值
*/
void eLinkAppendValue(ELink *eLink,ENode *value){
   if (eLink == NULL) {
       return;
   }
   assert(value != NULL);
   ENode *eNodel = &(eLink->head);
   for (int i = 0; i< eLink->count; i++) {
       eNodel = eNodel->nextNode;
   }
   eNodel->nextNode = value;
   eLink->count++;
}
/**
向链表里插入值
@param eLink 链表
@param value 添加的值
@param index 插入的位置
*/
void eLinkInsertValueOfIndex(ELink *eLink,ENode *value,int index){
   if (eLink == NULL) {
       return;
   }
   assert(value != NULL);
   assert(index >=0 && index <= eLink->count);
   ENode *eNodel = &(eLink->head);
   for (int i = 0; i< index; i++) {
       eNodel = eNodel->nextNode;
   }
   ENode *nextNodel = eNodel->nextNode;
   eNodel->nextNode = value;
   value->nextNode = nextNodel;
   eLink->count++;
}

/**
移除链表里的值
@param eLink 链表
@param index 移除的位置
*/
void eLinkRemoveOfIndex(ELink *eLink,int index){
   if (eLink == NULL) {
       return;
   }
   assert(index >= 0 && index < eLink->count);
   ENode *eNodel = &(eLink->head);
   for (int i = 0; i< index; i++) {
       eNodel = eNodel->nextNode;
   }
   eNodel->nextNode = eNodel->nextNode->nextNode;
   eLink->count--;
}

/**
打印链表
*/
void eLinkPrintf(ELink *eLink, void (*founction)(ENode *eNode)){
   ENode *eNode =&(eLink->head);
   for (int i = 0; i<eLink->count; i++) {
       eNode = eNode->nextNode;
       founction(eNode);
   }
}
/*
释放链表
@param eLink 链表
**/
void eLinkFree(ELink *eLink){
   if (eLink != NULL) {
       free(eLink);
   }
}