您的位置:首页 > 理论基础 > 数据结构算法

数据结构 线性链表

2016-07-17 23:16 204 查看
//线性链表头文件
#ifndef _vzhanglinklist
#define _vzhanglinklist

typedef struct _LinkNode{
struct _LinkNode *pnext;
}LinkNode;

typedef void LinkList;

//创建线性链表
_declspec(dllexport)
LinkList* LinkList_Create();

//销毁线性链表
_declspec(dllexport)
int LinkList_Destroy(LinkList** list);

//清空线性链表
_declspec(dllexport)
int LinkList_Clear(LinkList* list);

//获取线性链表长度
_declspec(dllexport)
int LinkList_Length(LinkList* list);

//线性链表指定位置插入元素
_declspec(dllexport)
int LinkList_Insert(LinkList* list, LinkNode* node, int pos);

//获取线性链表指定位置的元素
_declspec(dllexport)
LinkNode* LinkList_Get(LinkList* list, int pos);

//删除线性链表指定位置的元素
_declspec(dllexport)
LinkNode* LinkList_Delete(LinkList* list, int pos);

#endif;


//线性链表代码实现
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"LinkList.h"

/*
强调:①链表中不提供对元素的删除功能,因为链表无法知道元素的大小
②MyLinkList结构体应该定义在方法实现的文件中,不要定义在.h文件里
因为用户不需要知道MyLinkList结构体是怎么实现的
*/

//定义链表对象
typedef struct _MyLinkList{
//定义链表头结点
LinkNode head;
//定义链表元素个数
int length;
}MyLinkList;

//创建线性链表
_declspec(dllexport)
LinkList* LinkList_Create(){
//创建链表结构
MyLinkList *mylist = (MyLinkList *)malloc(sizeof(MyLinkList));
if (mylist==NULL)
{
printf("创建链表分配内存失败!\n");
return NULL;
}
mylist->head.pnext= NULL;
mylist->length = 0;
return (LinkList*)mylist;
}

//销毁线性链表
_declspec(dllexport)
int LinkList_Destroy(LinkList** list){
int ERRO_MSG = 0;
if (list == NULL)
{
ERRO_MSG = -1;
printf("list==NULL 传入参数不可以为空! erro msg:%d\n", ERRO_MSG);
return ERRO_MSG;
}
MyLinkList * mylist = (MyLinkList *)*list;
if (mylist!=NULL)
{
//链表的数据必须由用户删除
free(mylist);
mylist = NULL;
*list = NULL;
}
return ERRO_MSG;
}

//清空线性链表
_declspec(dllexport)
int LinkList_Clear(LinkList* list){
int ERRO_MSG = 0;
if (list == NULL)
{
ERRO_MSG = -1;
printf("list==NULL 传入参数不可以为空! erro msg:%d\n", ERRO_MSG);
return ERRO_MSG;
}
MyLinkList * mylist = (MyLinkList *)list;
mylist->head.pnext = NULL;
mylist->length = 0;
return ERRO_MSG;
}

//获取线性链表长度
_declspec(dllexport)
int LinkList_Length(LinkList* list){
int ERRO_MSG = 0;
if (list == NULL)
{
ERRO_MSG = -1;
printf("list==NULL 传入参数不可以为空! erro msg:%d\n", ERRO_MSG);
return ERRO_MSG;
}
MyLinkList * mylist = (MyLinkList *)list;
return mylist->length;
}

//线性链表指定位置插入元素
_declspec(dllexport)
int LinkList_Insert(LinkList* list, LinkNode* node, int pos){
int ERRO_MSG = 0,i=0;
if (list == NULL)
{
ERRO_MSG = -1;
printf("list==NULL 传入参数不可以为空! erro msg:%d\n", ERRO_MSG);
return ERRO_MSG;
}
MyLinkList * mylist = (MyLinkList *)list;
//此时current指针指向头结点  不指向第0个元素
LinkNode * current = &mylist->head;
for (i = 0; i < pos&&(current->pnext!=NULL); i++)
{
/*
current->pnext!=NULL这个判断不能缺少  这是为了链表元素的连续
也是为了current->pnext指针操作不报错
*/
current = current->pnext;
}
/*
当在第0个位置插入  正好current此时是头结点  所以没问题
*/
node->pnext = current->pnext;
current->pnext = node;
//元素个数+1
mylist->length++;
return ERRO_MSG;
}

//获取线性链表指定位置的元素
_declspec(dllexport)
LinkNode* LinkList_Get(LinkList* list, int pos){
int ERRO_MSG = 0, i = 0;
if (list == NULL)
{
ERRO_MSG = -1;
printf("list==NULL 传入参数不可以为空! erro msg:%d\n", ERRO_MSG);
return NULL;
}
MyLinkList * mylist = (MyLinkList *)list;
//判断获取元素的位置
if (pos<0 || pos>mylist->length)
{
ERRO_MSG = -2;
printf("该位置上没有元素! erro msg:%d\n", ERRO_MSG);
return NULL;
}
//
/*
注意:此时跟插入方法有区别
插入方法中,current指向的是头结点,在本方法中current指向的是第0个元素
这是为了 获取第0个位置的元素 方便
*/
LinkNode * current = mylist->head.pnext;
for (i = 0; i < pos; i++)
{
current = current->pnext;
}
return current;
}

//删除线性链表指定位置的元素
_declspec(dllexport)
LinkNode* LinkList_Delete(LinkList* list, int pos){
int ERRO_MSG = 0, i = 0;
if (list == NULL)
{
ERRO_MSG = -1;
printf("list==NULL 传入参数不可以为空! erro msg:%d\n", ERRO_MSG);
return NULL;
}
MyLinkList * mylist = (MyLinkList *)list;
//判断获取元素的位置
if (pos<0 || pos>mylist->length)
{
ERRO_MSG = -2;
printf("该位置上没有元素! erro msg:%d\n", ERRO_MSG);
return NULL;
}
//这里跟获取元素位置离又不相同  这里current指向的是头结点
LinkNode * current = &mylist->head;
LinkNode * ret = NULL;
for (i = 0; i < pos; i++)
{
current = current->pnext;
}
ret = current->pnext;
current->pnext = ret->pnext;
ret->pnext = NULL;
//元素个数-1
mylist->length--;
return ret;
}


//线性链表测试代码
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"LinkList.h"

typedef struct _Student{
//必须加一个LinkNode节点
LinkNode node;
char name[30];
int age;
}Student;

void Test(){
Student s1, s2, s3, s4, s5;
int numx = 0, i = 0, ret = 0;
strcpy(s1.name, "小米");
s1.age = 11;
strcpy(s2.name, "小刚");
s2.age = 12;
strcpy(s3.name, "小红");
s3.age = 10;
strcpy(s4.name, "啸天");
s4.age = 13;
strcpy(s5.name, "莲华");
s5.age = 12;
//线性表指针
LinkList *list = NULL;
//创建线性链表
list = LinkList_Create();
//插入元素
LinkList_Insert(list, (LinkNode *)&s1, 0);
LinkList_Insert(list, (LinkNode *)&s2, 0);
LinkList_Insert(list, (LinkNode *)&s3, 0);
LinkList_Insert(list, (LinkNode *)&s4, 0);
LinkList_Insert(list, (LinkNode *)&s5, 0);
//获取元素个数
numx = LinkList_Length(list);
//打印所有元素
for (i = 0; i < numx; i++)
{
Student *temp = (Student *)LinkList_Get(list, i);
printf("我的名字是%s;我的年龄是%d\n", temp->name, temp->age);
}
//删除线性表中的数据
Student *delem = (Student *)LinkList_Delete(list, 2);
printf("我被删除了,我的名字是%s;我的年龄是%d\n", delem->name, delem->age);
//销毁线性表
ret = LinkList_Destroy(&list);
if (ret == 0)printf("线性链表销毁成功!\n");
}

void main(){
Test();
system("pause");
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: