顺序表与链表

对于顺序表和链表的相关定义和优缺点,这里不加讲述,不了解的同学自行学习,也可参考该文章http://t.csdnimg.cn/3FUpU, 这里着重将一下其结构的基本的实现

一.顺序表

首先是顺序表的结构定义

typedef struct vector{
    int size, count;
    int *data;
}vector;

即,顺序表的中为data申请的内存大小size(这里指可存储的元素个数),以及实际存储的元素个数count,data指针指向一片内存空间。

接下来是顺序表的一些操作

1.创建顺序表

vector *init_Vector(int n){
    vector *p = (vector *)malloc(sizeof(vector)); //开辟顺序表空间
    p -> size = n;
    p -> count = 0;
    p -> data = (int *)malloc(sizeof(int) * n); 
    return p; 
}

2.顺序表的销毁

void clear(vector *p){
    if(p == NULL) return ;
    free(p -> data);
    free(p);
    return ;
}

3.顺序表的扩容(这里是最简单的二倍扩容)

int expand(vector *p){
    if(p == NULL) return 0;
    int *x = (int *)realloc(p -> data, sizeof(int) * p -> size * 2); //realloc重新分配内存空间
    if(x == NULL) return 0;
    printf("expand p from %d to %d\n", p -> size, 2 * p -> size);
    p -> data = x;
    p -> size *= 2;
    return 1;
}

4.顺序表的插入

int insert(vector *p, int pos, int val){
    if(pos < 0 || pos > p -> count) return 0;
    if(p -> size == p -> count && !expand(p)) return 0;
    for(int i = p -> count - 1; i >= pos; i--){
        p -> data[i + 1] = p -> data[i];
    }
    p -> data[pos] = val;
    p -> count++;
    return 1;
}

5.顺序表的删除

int erase(vector *p, int pos){
    if(pos < 0 || pos >= p -> count) return 0;
    for(int i = pos + 1; i < p -> count; i++){
        p -> data[i - 1] = p -> data[i];
    }
    p -> count--;
    return 1;
}

二.链表

首先是链表的结构定义

typedef struct node{
    struct node *next;
    int data;
} node;

其中data表示链表节点存储的数据,next表示该节点存储的下一个节点的地址

接下来是一些链表的操作

1.链表节点的创建

node *get_new_node(int val){
    node *p = (node *)malloc(sizeof(node));
    p -> data = val;
    p -> next = NULL;
    return p;
}

2.链表的销毁

void clear(node *head){
    if(head == NULL) return ;
    for(node *p = head, *q; p; p = q){
        q = p -> next;
        free(p);
    }
    return ;
}

注意:因为链表中存储的数据是离散型的,连接每一个链表节点的方式就死指针,所以在释放链表各节点的空间时,要防止因前一个节点释放后,导致后续的节点不能通过指针找到,即内存泄漏,所以需要再定义一个指针来存储被释放的节点中指针的信息。

3.链表的插入

对于无头链表的常规插入

node *insert(node *head, int pos, int val){
    if(pos == 0) {
        node *p = get_new_node(val);
        p -> next = head;
        return p;
    }
    node *p = head;
    for(int i = 1; i < pos; i++) p = p -> next;
    node *x = get_new_node(val);
    x -> next = p -> next;
    p -> next = x;
    return head;
}

利用有头链表的思想定义一个虚拟头结点进行插入

node *insert(node *head, int pos, int val){
    node new_head, *p = &new_head, *node = get_new_node(val); 
    //new_head虚拟头节点,p指向插入位置的前一位
    //node为插入的节点
    new_head.next = head;
    for(int i = 0; i < pos; i++) p = p -> next;
    node -> next = p -> next;
    p -> next = node;
    return new_head.next;
}

对于链表的其他操作,需要我们自行的去实现,对于实际的问题所运用到的操作是不同的,在理解链表的结构之后,对于具体题目就需要具体分析了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值