数据结构学习笔记-01单向表

295 阅读3分钟

算法复杂度

大O表示法

  1. 用常数1取代运行时间中所有常数 3->1 O(1)
  2. 在修改运行次数函数中,只保留最高阶项 n^3+2n^2+5 -> O(n^3)
  3. 如果在最高阶存在且不等于1,则去除这个项目相乘的常数 2n^3 -> n^3

时间复杂度

空间复杂度:算法执行时所需要的辅助空间,也是大O()表示法

线性表

  • 线性表->顺序存储(逻辑相邻,物理储存地址相邻)

单向链表实现

#import "stdio.h"
#import "stdlib.h"

#define OK 1
#define ERROR 0
typedef int Element,Status;

//定义结点
typedef struct Node {
    Element data;
    struct Node *next;
}Node;

typedef struct Node * LinkList;

//初始化单向链表
Status InitList(LinkList *list){
    //产生头结点
    *list = (LinkList)malloc(sizeof(Node));
    //如果空间分配失败
    if (*list == NULL) {
        return ERROR;
    }
    //将头节点的指针域置为空
    (*list)->next = NULL;
    return OK;
}

//增
Status insertData(LinkList *list,Element ele,int i) {
    int j = 1;
    LinkList p = *list;
    
    //寻找第i-1个节点
    while (p && j < i) {
        p = p->next;
        ++j;
    }
    
    //第i个元素不存在
    if (!p || j > i) {//j > i 防止i为负值 比如负 -1
        return ERROR;
    }
    
    //生成新节点s
    LinkList s = (LinkList)malloc(sizeof(Node));
    //将数据ele 赋值
    s->data = ele;
    //将p的后继节点赋值s的后继节点
    s->next = p->next;
    //将s赋值给p的后继
    p->next = s;
    
    return OK;
}

//删
Status deleteData(LinkList *list,int i,Element *e) {
    int j = 1;
    //拿到元节点
    LinkList p = (*list)->next;
    
    //如果p = null 或者j < i就退出,为的是拿到第i-1个节点
    while (p && j < i-1) {
        p = p->next;
        ++j;
    }
    
    //当i>n 或者 i<1 时,删除位置不合理
    if (!(p->next) || (j>i-1)) {
        return ERROR;
    }
    
    //q指向要删除的节点
    LinkList q = p->next;
    //将q的后继赋值给p的后继
    p->next = q->next;
    //赋值被删除的节点
    *e = q->data;
    //让系统回收此节点,释放内存
    free(q);
    
    return OK;
}

//改
Status changeData(LinkList *list,int i,Element e) {
    int j = 1;
    //拿到元节点
    LinkList p = (*list)->next;
    //如果p = null 或者j < i就退出,为的是拿到第i-1个节点
    while (p && j < i) {
        p = p->next;
        ++j;
    }
    
    //当i>n 或者 i<1 时,删除位置不合理
    if (!p || j > i) {
        return ERROR;
    }
    
    //修改节点数据
    p->data = e;
    
    return OK;
}

//查
Status queryData(LinkList list,int i,Element *e) {
    int j = 1;
    //获取元结点
    LinkList p = list->next;
    
    while (p && j<i) {
        //p指向下一个结点
        p = p->next;
        ++j;
    }
    
    //如果p为空或者j>i,则返回error
    if(!p || j > i) return ERROR;
    
    *e = p->data;
    return OK;
}

//清空
Status clearAllData(LinkList *list) {
    LinkList p = (*list)->next;//获取元节点
    LinkList q;//临时变量
    while (p->next) { //遍历
        q = p->next;
        free(p);//删除
        p = q;
    }
    (*list)->next = NULL; //头结点指针域为空
    return OK;
}

//遍历打印
Status traverseList(LinkList *list){
    LinkList p = (*list)->next;//获取元节点

    printf("\n");
    do {
        printf("%d\n",p->data);
        p = p->next;
    } while (p);
    printf("\n");
    return OK;
}

#define KLog printf("\n=======================\n");

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        NSLog(@"Hello, World!");
        
        Status kStatus;
        LinkList list;
        //初始化
        kStatus = InitList(&list);
        //增
        for (int i = 1; i < 10; i++) {
            insertData(&list, i, i);
        }
        traverseList(&list);
        KLog
        
        //删
        Element e;
        deleteData(&list, 5, &e);
        printf("被删除的是:%d",e);
        traverseList(&list);
        KLog
        
        //改
        changeData(&list, 3, 69);
        traverseList(&list);
        changeData(&list, 4, 46);
        traverseList(&list);
        KLog
        
        //查
        Element e1;
        queryData(list, 4, &e1);
        printf("查到的元素是:%d\n",e1);
        KLog
        
        //清除
        clearAllData(&list);
    }
    return 0;
}