对于顺序表和链表的相关定义和优缺点,这里不加讲述,不了解的同学自行学习,也可参考该文章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;
}
对于链表的其他操作,需要我们自行的去实现,对于实际的问题所运用到的操作是不同的,在理解链表的结构之后,对于具体题目就需要具体分析了。