前言
最近在复习数据结构,突然想起了之前用C和C++写的数据结构代码,现在将其发布到CSDN,方便日后查看。
DataElement.h
定义了数据元素
#ifndef DATAELEMENT_H_INCLUDED
#define DATAELEMENT_H_INCLUDED
#define MAX_SIZE 255
//1.定义数据元素
typedef struct{
int id;
char * name;
}ElementType;
//2.定义顺序表结构
typedef struct{
ElementType datas[MAX_SIZE]; //顺序表中数据元素的集合
int length; //当前顺序表中的元素个数
}SeqList;
#endif // DATAELEMENT_H_INCLUDED
LinkList.h
相当于Java的interface
//链表Demo
#ifndef LINKLIST_H_INCLUDED
#define LINKLIST_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include "DataElement.h"
/* 定义链表的结点 包含数据域和指针域*/
typedef struct Node
{
ElementType data; //数据域
struct Node * next; //指针域(没有错 前面的struct Node是类型 就比如int * next一个道理)
}Node;
//头结点
typedef struct LinkList
{
Node * next; //头指针 如果链表有头结点,next就指向头结点。如果没有就指向第一个结点
int length; //链表的长度,初始值为0;
}LinkList;
//初始化链表
void InitLinkList(LinkList * linkList,ElementType * dataArray, int length);
//在制定的位置pos处插入元素element
void InsertLinkList(LinkList * linkList, int pos, ElementType element);
//删除链表中的位置为pos的结点;
ElementType DeleteLinkList(LinkList * linkList, int pos);
//打印链表
void PrintLinkList(LinkList * linkList);
#endif // LINKLIST_H_INCLUDED
LinkList.c
LinkList.h的实现文件
#include "LinkList.h"
void InitLinkList(LinkList * linkList,ElementType * dataArray, int length)
{
for(int i = 0; i < length; i++){
InsertLinkList(linkList, i + 1, dataArray[i]);
}
}
void InsertLinkList(LinkList * linkList, int pos, ElementType element)
{
//1.创建空结点并给数据域赋值
Node * node = (Node*)malloc(sizeof(Node));
node->data = element;
node->next = NULL; //初始化置空
//2.找到要插入位置的结点
if(pos == 1) //如果插入的是第一个元素(问题在于 左边的接上了,右边没有接上 node的next域还是NULL)
{
node->next = linkList->next; //接上右边
linkList->next = node; //接上左边 //头指针指向了新创建的结点
linkList->length++;
return;
}
//通过循环找到要插入结点的位置
Node * currNode = linkList->next;//又创建了一个结点,这个结点指向头指针指向的地方(第一个结点)
for(int i = 1; currNode && i < pos - 1; i++)
{
currNode = currNode->next;
}
//将结点插入并对接前面的结点
if(currNode)
{
node->next = currNode->next;
currNode->next = node;
linkList->length++;
}
}
ElementType DeleteLinkList(LinkList * linkList, int pos)
{
ElementType element; //要删除的元素。这个变量就是保存要删除的元素
element.id = -999; //附一个不可能的值,验证是否删除成功
Node * node = NULL;
if(pos == 1) //如果要删除的结点是第一个结点
{
node = linkList->next;
if(node)
{
element = node->data;
linkList->next = node->next;
free(node); //释放被删除结点的内存
linkList->length--;
}
return element;
}
//1.找到要删除结点和他的前缀结点
//2.要删除结点的next赋值给前缀结点的next
//3.释放要删除的节点内存
Node * preNode; //前缀结点
node = linkList->next;
for(int i = 1; i < pos && node; i++)
{
preNode = node; //保存node之前的那个结点(前缀结点)
node = node->next;
}
if(node)
{
element = node->data;
preNode->next = node->next;
free(node);
linkList->length--;
}
return element;
}
void PrintLinkList(LinkList * linkList)
{
Node * node = linkList->next;
if(!node)
{
printf("链表为空\n");
linkList->length = 0;
return;
}
for(int i = 0; i < linkList->length; i++)
{
printf("%d\t%s\n",node->data.id,node->data.name);
node = node->next;
}
}
main.c
这里是主函数,相当于Java的测试类。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "DataElement.h"
#include "LinkList.h"
ElementType dataArray[] = {
{1,"van"},
{2,"billy"},
{3,"banana"},
{4,"亚索"}
};
void TestLinkList();
int main()
{
TestLinkList();
return 0;
}
void TestLinkList()
{
LinkList linkList;
linkList.length = 0; //非常容易忽略。初始化长度为0
InitLinkList(&linkList, dataArray, sizeof(dataArray) / sizeof(dataArray[0]));
PrintLinkList(&linkList);
ElementType element;
element.id = 123;
element.name = (char*)malloc(10);
strcpy(element.name, "木吉");
InsertLinkList(&linkList, 2 , element);
printf("插入后\n");
PrintLinkList(&linkList);
printf("删除第三个元素后\n");
ElementType beenDeleted = DeleteLinkList(&linkList, 3);
PrintLinkList(&linkList);
printf("被删除的元素是\n");
printf("%d\t%s\n",beenDeleted.id,beenDeleted.name);
}