第六周周报
这个星期大部分精力花在了海贼课上,所以对海贼课的内容进行了一个小总结
顺序表,也即是动态数组vector,需要学习的重难点在于其扩容的部分。
typedef struct Vector {
int size;
int length;
int *data;
} Vector;
void init(Vector *vector,int n) {
vector->size=n;
vector->data=(int*)malloc(sizeof(int)*n);
vector->length=0;
}
首先是定义部分,定义一个指针后面指向需要开辟的数组空间,然后是数组大小,以及数据内容大小。注意到这个数组的大小是自己指定出来的。
void expand(Vector *vector) {
if(vector->length>=vector->size)
{
vector->size=vector->size*2;
int *old_data=vector->data;
vector->data=(int*)malloc(sizeof(int)*vector->size);
for(int i=0;i<vector->length;i++)
{
vector->data[i]=old_data[i];
}
free(old_data);
}
}
int insert(Vector *vector,int pos,int value) {
if(pos<0||pos>vector->length)
{
return ERROR;
}
if(vector->length>=vector->size)
{
expand(vector);
}
for(int i=vector->length;i>pos;i--)
{
vector->data[i]=vector->data[i-1];
}
vector->data[pos]=value;
vector->length++;
return OK;
}
int search(Vector *vector,int value) {
for(int i=0;i<vector->length;i++)
{
if(vector->data[i]==value)
{
return i;
}
}
return -1;
}
int delete_node(Vector *vector,int pos) {
if(pos<0||pos>vector->length)
{
return ERROR;
}
for(int i=pos;i<vector->length-1;i++)
{
vector->data[i]=vector->data[i+1];
}
vector->length--;
return OK;
}
void print(Vector *vector) {
for(int i=0;i<vector->length;i++)
{
if(i>0)
printf(" ");
printf("%d",vector->data[i]);
}
printf("\n");
}
void clear(Vector *vector) {
free(vector->data);
free(vector);
}
扩容操作:当大小超出的时候,拿一个指针指向原来的数组,再开辟一个原来两倍大小的数组空间,再将原来的数组转移到新数组中。
插入操作,把pos位置之后的数全部往后移动一位,再在pos处插入value.
查询就是一个普通的for循环遍历
删除是把pos处之后的全部往前移动一位即可。
打印和查询类似。
最后因为用了malloc开辟了空间,之后记得要将空间使用free释放掉。
这是实际过程中的操作,除了用stl的vector之外,也有一个小技巧,就是因为算法题一般空间是足够的,时间限制比较紧。所以可以通过开一个巨大的数组解决动态数组的问题
创造一个全局变量const int N=1e6+10;int q[N];即可达成目的。
链表
定义,链表定义就是一个数据类型和一个指向下一个的指针next,特别的要起一个指针别名方便之后的操作
#include <stdio.h>
#include <stdlib.h>
typedef struct Node{
int data;
struct Node *next;
}Node, *LinkedList;
LinkedList insert(LinkedList head, Node *node, int index) {
if (head == NULL) {
if (index != 0) {
printf("failed\n");
return head;
}
head = node;
printf("success\n");
return head;
}
if (index == 0) {
node->next = head;
head = node;
printf("success\n");
return head;
}
Node *current_node = head;
int count = 0;
while (current_node->next != NULL && count < index - 1) {
current_node = current_node->next;
count++;
}
if (count == index - 1) {
node->next = current_node->next;
current_node->next = node;
printf("success\n");
return head;
}
printf("failed\n");
return head;
}
void output(LinkedList head) {
if (head == NULL) {
return;
}
Node *current_node = head;
while (current_node != NULL) {
printf("%d ", current_node->data);
current_node = current_node->next;
}
printf("\n");
}
LinkedList delete_node(LinkedList head, int index) {
if(head==NULL)
{return head;
printf("failed\n");}
if(index==0)
{
Node *delete_node=head;
head=head->next;
free(delete_node);
printf("success\n");
return head;
}
Node *current_node=head;
int count=0;
while(current_node!=NULL&&count<index-1)
{
current_node=current_node->next;
count++;
}
if(count==index-1&¤t_node->next!=NULL)
{
Node *delete_node=current_node->next;
current_node->next=delete_node->next;
free(delete_node);
printf("success\n");
}
else
printf("failed\n");
return head;
}
LinkedList reverse(LinkedList head) {
if(head==NULL)
return head;
Node *current_node,*next_node;
current_node=head->next;
head->next=NULL;
while(current_node!=NULL)
{next_node=current_node->next;
current_node->next=head;
head=current_node;
current_node=next_node;}
return head;
}
void clear(LinkedList head) {
Node *current_node = head;
while (current_node != NULL) {
Node *delete_node = current_node;
current_node = current_node->next;
free(delete_node);
}
}
插入操作,首先看头结点是否为空,如果头结点为空,则只能插入头结点,头结点不为空,要去找到要插入的节点,然后在其和其next之间插入。
删除操作,首先找到删除节点前一个节点,让火车断开,再释放掉删除点的空间。
查询和删除类似。
链表翻转,这里要注意,首先让头结点断开。current指向其下一个,然后让nextnode指向current下一个,current指向头,让current变成头结点,再让next成为下一个current.
在做题的时候我们可以采取用数组模拟的办法去模拟这一个过程。
// head存储链表头,e[]存储节点的值,ne[]存储节点的next指针,idx表示当前用到了哪个节点
int head, e[N], ne[N], idx;
// 初始化
void init()
{
head = -1;
idx = 0;
}
// 在链表头插入一个数a
void insert(int a)
{
e[idx] = a, ne[idx] = head, head = idx ++ ;
}
// 将头结点删除,需要保证头结点存在
void remove()
{
head = ne[head];
}