数据结构 链式存储 +

int DeleteLinkList(LinkList *list, char *name);

int ReviseLinkList(LinkList *list, char *name, DATATYPE data);

int DestroyLinkList(LinkList *list);

int InsertTailLinkList(LinkList *list, DATATYPE data);

​​​​​​​删除

修改​​​​​​​

销毁

​​​​​​​

插入

完整代码展示

cpp 复制代码
#include <stdio.h>
#include "doulink.h"
#include <string.h>
int findbyname(DATATYPE*data,void* arg)
{
    return (0 == strcmp(data->name,(char*)arg));
}
int findbyage(DATATYPE*data,void* arg)
{
    return data->age == *(int*)arg;
}
int main()
{
    DATATYPE data[5]={
        {"zhangsan",'m',20,70},
        {"lisi",'f',21,60},
        {"wangmazi",'m',25,80},
        {"liubei",'f',30,85},
        {"caocao",'f',40,90},
    };

    DouLinkList* dl = CreateDouLinkList();

    InsertHeadLinkList(dl,&data[0]);
    InsertHeadLinkList(dl,&data[1]);
    InsertHeadLinkList(dl,&data[2]);

    ShowDouLinkList(dl,DIR_FORWARD);
    printf("-------------back---------------\n");
    ShowDouLinkList(dl,DIR_BACKWARD);
    printf("-------------find---------------\n");
    //    char want_name[]="lisi";
    //    //DouLinkNode* tmp = FindLinkList(dl,findbyname,want_name);
    //    int want_age = 25;
    //    DouLinkNode* tmp = FindLinkList(dl,findbyage,&want_age);
    //    if(NULL == tmp)
    //    {
    //        printf("can't find person ,name:%s\n",want_name);
    //    }
    //    else
    //    {

    //        printf("%s:%d\n",tmp->data.name,tmp->data.score);
    //    }

    //    RevertDouLinkList(dl);
    //    printf("-------------rev---------------\n");
    //    ShowDouLinkList(dl,DIR_FORWARD);
    //    DeleteLinkList(dl,findbyname,"lisi");
    //    printf("-------------del forware---------------\n");
    //    ShowDouLinkList(dl,DIR_FORWARD);
    //    printf("-------------back---------------\n");
    //    ShowDouLinkList(dl,DIR_BACKWARD);

    //    ModifyDouLinkList(dl,findbyname,"zhangsan",&data[3]);
    //    printf("-------------modify---------------\n");
    //    ShowDouLinkList(dl,DIR_FORWARD);

    InserPosDouLinkList(dl,&data[3],3);
    printf("-------------pos---------------\n");
    ShowDouLinkList(dl,DIR_FORWARD);
    printf("-------------back---------------\n");
    ShowDouLinkList(dl,DIR_BACKWARD);


    DestroyDouLinkList(&dl);

    printf("Hello World!\n");
    return 0;
}
cpp 复制代码
#include "doulink.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

DouLinkList *CreateDouLinkList()
{
    //DouLinkList dl ;
    DouLinkList* dl = (DouLinkList*)malloc(sizeof(DouLinkList));
    if(NULL == dl)
    {
        perror("CreateDouLinkList malloc");
        //exit(1);
        return NULL;
    }
    dl->head =NULL;
    dl->clen = 0 ;

    return dl;
}

int InsertHeadLinkList(DouLinkList *list, DATATYPE *data)
{
    DouLinkNode*newnode = malloc(sizeof(DouLinkNode));
    if(NULL == newnode)
    {
        perror("InsertHeadLinkList malloc");
        return 1;
    }
    memcpy(&newnode->data,data,sizeof(DATATYPE));
    newnode->next = NULL;
    newnode->prev= NULL;

    if(0==list->clen)//empty
    {
        list->head = newnode;
    }
    else
    {
        newnode->next = list->head;
        list->head->prev = newnode;
        list->head = newnode;
    }
    list->clen++;
    return 0;


}

int ShowDouLinkList(DouLinkList *list, DIRECT direct)
{
    int i = 0 ;
    DouLinkNode* tmp = list->head;
    if(direct==DIR_FORWARD)
    {
        for(i=0;i<GetSizeDouLinkList(list);i++)
        {
            printf("%s %c %d %d\n",tmp->data.name,tmp->data.sex,tmp->data.age,tmp->data.score);
            tmp=tmp->next;
        }
    }
    else
    {
        while(tmp->next)
        {
            tmp=tmp->next;
        }
        for(i=0;i<GetSizeDouLinkList(list);i++)
        {
            printf("%s %c %d %d\n",tmp->data.name,tmp->data.sex,tmp->data.age,tmp->data.score);
            tmp=tmp->prev;
        }
    }
    return 0;
}

int GetSizeDouLinkList(DouLinkList *list)
{
    return list->clen;
}

DouLinkNode *FindLinkList(DouLinkList *list, PFUN fun, void *arg)
{
    DouLinkNode* tmp = list->head;
    int size = GetSizeDouLinkList(list);
    int i =  0;
    for(i = 0 ;i<size;i++)
    {
        //if(0==strcmp(tmp->data.name))
        if(fun(&tmp->data,arg))
        {
            return tmp;
        }
        tmp= tmp->next;
    }
    return NULL;
}

int RevertDouLinkList(DouLinkList *list)
{
    int size = GetSizeDouLinkList(list);
    if(size<2)
    {
        return 0;
    }

    DouLinkNode* prev= NULL;
    DouLinkNode* tmp = list->head;
    DouLinkNode*next= tmp->next;
    while(1)
    {
        tmp->next = prev;
        tmp->prev = next;
        prev= tmp;
        tmp = next;
        if(NULL == tmp)
        {
            break;
        }
        next =next->next;
    }
    list->head = prev;
    return 0;
}

int DeleteLinkList(DouLinkList *list, PFUN fun, void *arg)
{
    if(NULL == list)
    {
        fprintf(stderr,"DouLinkList is null");
        return 1;
    }
    if(IsEmptyDouLinkList(list))
    {
        fprintf(stderr,"DouLinkList is empty");
        return 1;
    }
    DouLinkNode* ret = FindLinkList(list,fun,arg);
    if(NULL==ret)
    {
        fprintf(stderr,"DeleteLinkList error,cant find\n");
        return 1;
    }
    if(ret == list->head)
    {
        list->head = ret->next;
        list->head->prev = NULL;
    }
    else
    {
        if(ret->next)
        ret->next->prev = ret->prev;
        ret->prev->next = ret->next;
    }

    free(ret);
    list->clen--;
    return 0;
}

int IsEmptyDouLinkList(DouLinkList *list)
{
    return 0 == list->clen;
}

int ModifyDouLinkList(DouLinkList *list, PFUN fun, void *arg, DATATYPE *data)
{
    DouLinkNode* ret = FindLinkList(list,fun,arg);
    if(NULL == ret)
    {
        fprintf(stderr,"ModifyDouLinkList error,cant find\n");
        return 1;
    }
    memcpy(&ret->data,data,sizeof(DATATYPE));
    return 0;
}

int DestroyDouLinkList(DouLinkList **list)
{
    DouLinkNode* tmp=(*list)->head;
    while(tmp)
    {
    (*list)->head=(*list)->head->next;
    free(tmp);
    tmp = (*list)->head;

    }
    free(*list);
    (*list)= NULL;
    return 0;
}

int InserPosDouLinkList(DouLinkList *list, DATATYPE *data,int pos)
{
    if(pos<0 ||pos>GetSizeDouLinkList(list))
    {
        fprintf(stderr,"InserPosDouLinkList error,index error\n");
        return 1;

    }
    if(IsEmptyDouLinkList(list) || 0 == pos)
    {
        return InsertHeadLinkList(list,data);
    }
    else
    {
        DouLinkNode* tmp = list->head;
        tmp= list->head;
        DouLinkNode* newnode = (DouLinkNode*)malloc(sizeof(DouLinkNode));
        if(NULL == newnode)
        {
            perror("InserPosDouLinkList malloc");
            return 1;
        }
        memcpy(&newnode->data,data,sizeof(DATATYPE));
        newnode->prev = NULL;
        newnode->next = NULL;
        int i = pos-1;
        while(i--)
        {
            tmp=tmp->next;
        }
        newnode ->prev = tmp;
        newnode->next = tmp->next;//这时候都是NULL,如果是尾插入不走if

        if(tmp->next)
        {
        tmp->next->prev = newnode;//中间插入
        }
        tmp->next = newnode;
    }
    list->clen++;
    return 0;
}
cpp 复制代码
#ifndef DOULINK_H
#define DOULINK_H
typedef struct{
    char name[32];
    char sex;
    int age;
    int score;
}DATATYPE;
typedef int (*PFUN)(DATATYPE*data,void* arg);//表示fun()中的参数书形式
typedef struct node {
    DATATYPE data;
    struct node *next,*prev;
}DouLinkNode;

typedef struct{
    DouLinkNode *head;
    int clen;
}DouLinkList;
typedef enum{DIR_FORWARD,DIR_BACKWARD}DIRECT;
DouLinkList* CreateDouLinkList();
int InsertHeadLinkList(DouLinkList *list, DATATYPE *data);
int ShowDouLinkList(DouLinkList *list,DIRECT direct);
int GetSizeDouLinkList(DouLinkList *list);
DouLinkNode *FindLinkList(DouLinkList *list, PFUN fun,void* arg);
int RevertDouLinkList(DouLinkList *list);
int DeleteLinkList(DouLinkList *list, PFUN fun,void* arg);
int IsEmptyDouLinkList(DouLinkList *list);
int ModifyDouLinkList(DouLinkList *list,PFUN fun,void* arg,DATATYPE *data);
int DestroyDouLinkList(DouLinkList **list);
int InserPosDouLinkList(DouLinkList *list,DATATYPE *data,int pos);
#endif // DOULINK_H

序表和链表 优缺点

存储方式:

顺序表是一段连续的存储单元

链表是逻辑结构连续物理结构(在内存中的表现形式)不连续

时间性能,

查找 顺序表O(1)

链表 O(n)

插入和删除

顺序表 O(n)

链表 O(1)

空间性能

顺序表 需要预先分配空间,大小固定

链表, 不需要预先分配,大小可变,动态分配

循环链表

简单的来说,就是将原来单链表中最有一个元素的next指针指向第一个元素或头结点,链表就成了一个环,头尾相连,就成了循环链表。circultlar linker list.

注意非空表,和空表。多数会加入头结点。

原来结束的条件是

p->next != NULL ------->>>>> p-next != Head

双向链表

double link list。

typedef struct DulNode

{

ElemType date;

struct DulNode *pri;

sturct DulNode *next;

}DulNode,*DuLinkList;

习题

1)双向链表逆序

2)实现mplay的播放列表

main.c

cpp 复制代码
#include <stdio.h>
#include "doulink.h"
#include <string.h>
#include "func.h"
#include <stdlib.h>
void show_menu( DouLinkList* dl)
{
    printf("1.show_list\n");
    printf("2.prev\n");
    printf("3.next\n");
    printf("4.end\n");
    char buf[10]={0};
    fgets(buf,sizeof(buf),stdin);
    int num = atoi(buf);
    switch (num) {
    case 1:
        ShowDouLinkList(dl,DIR_FORWARD);
        break;
    case 2:
        GetPrev(dl);
        break;
    case 3:
        Getnext(dl);
        break;
    case 4:
        exit(1);
        break;
    default:
        break;
    }
}
int main()
{
    DouLinkList* dl = CreateDouLinkList();
    do_ls("/home/linux",dl);

    ShowDouLinkList(dl,DIR_FORWARD);
    char *pathname=NULL;
    while(1)
    {
         show_menu(dl);
         pathname = GetCurrent(dl);
         printf("currnt play file:%s\n",pathname);

    }


    //atexit();
    printf("Hello World!\n");
    return 0;
}

doulink.c

cpp 复制代码
#include "doulink.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

DouLinkList *CreateDouLinkList()
{
    //DouLinkList dl ;
    DouLinkList* dl = (DouLinkList*)malloc(sizeof(DouLinkList));
    if(NULL == dl)
    {
        perror("CreateDouLinkList malloc");
        //exit(1);
        return NULL;
    }
    dl->head =NULL;
    dl->clen = 0 ;
    dl->currnet =NULL;

    return dl;
}

int InsertHeadLinkList(DouLinkList *list, DATATYPE *data)
{
    DouLinkNode*newnode = malloc(sizeof(DouLinkNode));
    if(NULL == newnode)
    {
        perror("InsertHeadLinkList malloc");
        return 1;
    }
    memcpy(&newnode->data,data,sizeof(DATATYPE));
    newnode->next = NULL;
    newnode->prev= NULL;

    if(0==list->clen)//empty
    {
        list->head = newnode;
    }
    else
    {
        newnode->next = list->head;
        list->head->prev = newnode;
        list->head = newnode;
    }
    list->clen++;
    return 0;


}

int ShowDouLinkList(DouLinkList *list, DIRECT direct)
{
    int i = 0 ;
    DouLinkNode* tmp = list->head;
    if(direct==DIR_FORWARD)
    {
        for(i=0;i<GetSizeDouLinkList(list);i++)
        {
            printf("%d %s\n",i,tmp->data.pathname);
            tmp=tmp->next;
        }
    }

    return 0;
}

int GetSizeDouLinkList(DouLinkList *list)
{
    return list->clen;
}

DouLinkNode *FindLinkList(DouLinkList *list, PFUN fun, void *arg)
{
    DouLinkNode* tmp = list->head;
    int size = GetSizeDouLinkList(list);
    int i =  0;
    for(i = 0 ;i<size;i++)
    {
        //if(0==strcmp(tmp->data.name))
        if(fun(&tmp->data,arg))
        {
            return tmp;
        }
        tmp= tmp->next;
    }
    return NULL;
}

int RevertDouLinkList(DouLinkList *list)
{
    int size = GetSizeDouLinkList(list);
    if(size<2)
    {
        return 0;
    }

    DouLinkNode* prev= NULL;
    DouLinkNode* tmp = list->head;
    DouLinkNode*next= tmp->next;
    while(1)
    {
        tmp->next = prev;
        tmp->prev = next;
        prev= tmp;
        tmp = next;
        if(NULL == tmp)
        {
            break;
        }
        next =next->next;
    }
    list->head = prev;
    return 0;
}



char *GetCurrent(DouLinkList *list)
{
    return list->currnet->data.pathname;
}

int GetPrev(DouLinkList *list)
{
    list->currnet = list->currnet->prev;
    if(NULL == list->currnet)
    {

        list->currnet = list->head;
        while(list->currnet->next)
        {
            list->currnet = list->currnet->next;
        }

    }
    return 0;

}

int Getnext(DouLinkList *list)
{
     list->currnet = list->currnet->next;
     if(NULL == list->currnet)
     {
           list->currnet = list->head;

     }
     return 0;
}

fun.c

cpp 复制代码
#include "func.h"
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int do_ls(char *path,DouLinkList*dl)
{
    {

        DIR* dir = opendir(path);
           if(NULL == dir)
           {
               printf("opendir");
               return 1;
           }
            DATATYPE data;
           while(1)
           {
               struct dirent *info =  readdir(dir);
               //procintf("%s  %lu",info->d_name,info->d_ino);
               if(NULL == info)
               {
                   break;
               }
               if(strlen(info->d_name ) >3)// 1.flv  /home/linux/1.flv
               {
                   if(0==strcmp(&info->d_name[strlen(info->d_name)-3],"mp3")
                      ||0==strcmp(&info->d_name[strlen(info->d_name)-3],"flv")
                      ||0==strcmp(&info->d_name[strlen(info->d_name)-3],"mp4"))
                   {
                       bzero(&data,sizeof(data));

                       sprintf(data.pathname,"%s/%s",path,info->d_name);
                       //sprintf(song.songlist[song.total++],"%s/%s",path,info->d_name);
                       InsertHeadLinkList(dl,&data);


                   }
               }
               else
               {
                   continue;
               }
           }
           closedir(dir);
    }
     dl->currnet = dl->head;
    return 0;
}

fun.h

cpp 复制代码
#ifndef FUNC_H
#define FUNC_H
#include "doulink.h"
int do_ls(char *path,DouLinkList*dl);

#endif // FUNC_H

doulink.h

cpp 复制代码
#ifndef DOULINK_H
#define DOULINK_H
typedef struct{
    char pathname[512];
}DATATYPE;
typedef int (*PFUN)(DATATYPE*data,void* arg);
typedef struct node {
    DATATYPE data;
    struct node *next,*prev;

}DouLinkNode;

typedef struct{
    DouLinkNode *head;
    struct node *currnet;
    int clen;
}DouLinkList;
typedef enum{DIR_FORWARD,DIR_BACKWARD}DIRECT;
DouLinkList* CreateDouLinkList();
int InsertHeadLinkList(DouLinkList *list, DATATYPE *data);
int ShowDouLinkList(DouLinkList *list,DIRECT direct);
int GetSizeDouLinkList(DouLinkList *list);
DouLinkNode *FindLinkList(DouLinkList *list, PFUN fun,void* arg);
int RevertDouLinkList(DouLinkList *list);
char* GetCurrent(DouLinkList *list);
 int GetPrev(DouLinkList *list);
 int Getnext(DouLinkList *list);
#endif // DOULINK_H
相关推荐
@小博的博客8 分钟前
C++初阶学习第十弹——深入讲解vector的迭代器失效
数据结构·c++·学习
泉崎2 小时前
11.7比赛总结
数据结构·算法
你好helloworld2 小时前
滑动窗口最大值
数据结构·算法·leetcode
JSU_曾是此间年少3 小时前
数据结构——线性表与链表
数据结构·c++·算法
sjsjs113 小时前
【数据结构-合法括号字符串】【hard】【拼多多面试题】力扣32. 最长有效括号
数据结构·leetcode
blammmp4 小时前
Java:数据结构-枚举
java·开发语言·数据结构
昂子的博客5 小时前
基础数据结构——队列(链表实现)
数据结构
lulu_gh_yu5 小时前
数据结构之排序补充
c语言·开发语言·数据结构·c++·学习·算法·排序算法
~yY…s<#>7 小时前
【刷题17】最小栈、栈的压入弹出、逆波兰表达式
c语言·数据结构·c++·算法·leetcode
XuanRanDev8 小时前
【每日一题】LeetCode - 三数之和
数据结构·算法·leetcode·1024程序员节