第二周的学习—数据结构初阶
一.顺序表的知识
1.顺序表的设置
typedef struct SeqList{
DateType* a; //这里用指针表示数组更加方便
int size; //表示当前的所达到的容量,是容量。但是a中最后一个元素是a[size-1];
int capacity;//总容量
}SQL;
2.顺序表的初始化
void SeqListInit(SQL*ps){
assert(ps);
ps->a=NULL;
ps->size=ps->capacity=0;
}//顺序表的初始化
3.顺序表的打印
void print(SQL*ps){
assert(ps);
for(int i=0;i<ps->size;i++){
printf("%d->",ps->a[i]);
}
printf("\n");
}//顺序表的打印
4.检查顺序表是否为空
void checkcapacity(SQL*ps){
int newcapacity=ps->capacity==0?4:2*ps->capacity;
DateType* p=(DateType*)realloc(ps->a,sizeof(SQL)*newcapacity);
if(p==NULL){
return ;
}
else{
ps->a=p;
ps->capacity=newcapacity;
return;
}
} //检查是否是空的,如果是的话,就扩容为4,否则扩为原来的两倍
5.顺序表的尾插
void pushback(SQL* ps,int elem){
assert(ps);
checkcapacity(ps);// 检查是否是空的,如果是的话,就扩容为4,否则扩为原来的两倍
ps->a[ps->size]=elem;//直接在尾部做文章
ps->size++;
return ;
}//顺序表的尾插
6.顺序表的头插
void pushhead(SQL* ps,int elem){
assert(ps);
checkcapacity(ps);
for(int i=ps->size;i>0;i--){
ps->a[i]=ps->a[i-1];//让每一个元素都向后移动一位,为了避免重复覆盖,当然是从最后一个开始。ps[size]原本应该是没有元素的,ps[size-1]的值传给了ps[size];故最后让size++
}
ps->a[0]=elem;
ps->size++;
return ;
} //顺序表的头插
7.顺序表的头删
void deletehead(SQL* ps){
assert(ps->size>0);
for(int i=0;i<ps->size-1;i++){
ps->a[i]=ps->a[i+1];//从第二个开始后一个覆盖前一个
ps->size--;//当前容量--
}
return ;
} //顺序表的头删
8.顺序表的尾删
void deletetail(SQL* ps){
assert(ps->size>0);
ps->size--;
}//顺序表的尾删
9.顺序表查找元素
int find(SQL* ps,int elem){
int i;
assert(ps);
assert(ps->size>0);
for( i=0;i<ps->size;i++){
if(ps->a[i]==elem){
return i;//返回的是下标数
}
else{
return -1;
}
}
}
10.顺序表的插入
void insert(SQL* ps,int index,int elem){
assert(ps);
assert(ps->size>index);
checkcapacity(ps);
for(int i=ps->size;i>index;i--){
ps->a[i]=ps->a[i-1];//从第index到最后一个的元素,每个元素往后移动,给第index腾出位置
}
ps->a[index]=elem;
ps->size++;
return ;
}//在第index的位置上插入elem;
11.顺序表的删除
void erase(SQL* ps,int index){
assert(ps);
for(int i=index;i<ps->size-1;i++){
ps->a[i]=ps->a[i+1];
}
ps->size--;
return ;
} //删除第index个元素
12.返回已经占有元素的个数
int size(SQL* ps){
assert(ps);
return ps->size;
}
13.更改第index个元素
void at(SQL* ps, int elem,int index){
assert(ps);
assert(ps->size>index);
ps->a[index]=elem;
return ;
}
14.顺序表的销毁
void ruin(SQL* ps){
assert(ps);
if(ps->a!=NULL){
free(ps->a);
ps->a=NULL;
}
return ;
}
15.主体部分
int main()
{
struct SeqList s={NULL,1,1};
SeqListInit(&s);
int n=0;
scanf("%d",&n);
for(int i=0;i<n;i++){
int val=0;
scanf("%d",&val);
pushback(&s,val);
}
print(&s);
}
二.单链表的知识
单链表节点的定义
typedef struct linknode{
int date;
struct linklist* next;
} node;//节点有有部分组成,当前数据和指向下一个节点的指针
1.创建头结点
node* Init(){
struct linklist* header=(struct linklist*)malloc(sizeof(struct linknode));
newnode->date=-1;
newnode->next=NULL;
return header;
}//创建头节点
2.创建一个新节点
node* crlinknode(int val){
struct linknode* newnode=(struct linknode*)malloc(sizeof(struct linknode));
newnode->date=val;
newnode->next=NULL;
return newnode;
}//生成一个新节点
3.将后一个插到头部去
void addnodehead(struct linklist*header,struct linklist*p){
p->next=header->next;
header->next=p;
}//将p插到头部去
4.将后一个插到尾部去
void addnodetail(struct linklist*header,struct linklist*p){
while(header->next){
header=header->next;
}
header->next=p;
p->next=NULL;
}
5.头插法创建链表
void addbyhead(struct linknode* header,int n){
for(int i=0;i<n;i++){//n表示要插入节点的个数
int val=0;
scanf("%d",&val);
addnodehead(header,crlinklist(val));
}
}//头插法创建链表
6.尾插法创建链表
void addbytail(struct linknode* header,int n){
for(int i=0;i<n;i++){
int val=0;
scanf("%d",&val);
addbytail(header,crlinknode(val));
}
}
7.打印链表
void print(struct linknode*header){
header=header->next;//跳过头结点
while(header){
printf("%d",header->date);
header->next;
}
}
8.找到第index个节点的前一个节点(方便让第index个节点插入或者删除)
linklist* seeknode(struct linlist*header,int index){
while(--index){
if(!header->next){
return NULL;
}
header=header->next;
}
return header;
}
9.删除第index个链表
void deletenode(struct linklist* header,int index){
header=seeknode(header,index);
struct linklist*p;
p=header->next;
header->next=p->next;
free(p);
}
10.替换数据
void atnode(struct linklist*header,int index,int val){
header=seeknode(header,index);
header->next->date=val;
}
11.反转链表
void reverse(struct linklist* header){
struct linklist* p=header->next;
struct linklist*s=p;
while(p){
s=p;
p=p->next;
s->next=header->next;
header->next=s;
}
return ;
}
三.栈的相关知识
首先,出栈入栈都是在顶部操作的
top始终是在有效数据的上一位
栈的定义
typedef struct stack{
DateType* date;
int top;
int capacity;
}ST;
1.栈的初始化
void StackInit(ST* ps){
ps->daye=NULL;
ps->top=ps->capacity=0;
}
2.扩容
void Stackadd(ST* ps){
if(ps->top==ps->capacity){
int newcapacity= (ps->capacity==0?4:2*capacity);
int* h=(int*)realloc(ps->date,(int)*newcapacity);
if(h==NULL){
exit(-1);
}
ps->date=h;
ps->capacity=newcapacity;
}
return ;
}
3.判断栈是否为空
void StackEmpty(ST* ps){
assert(ps);
return ps->capacity==0;
}
4.入栈
void StackPush(ST* ps,int i){
assert(ps);
Stackadd(ST* ps);
ps->date[ps->top++]=i;
return ;
}
5.出栈
void Stackpop(ST* ps){
assert(ST* ps);
ps->top--;
}
6.第top个的数
int readtop(ST* ps){
assert(ps);
return ps->date[top-1];
}
四.队列的相关知识
struct QueueNnode{
int date;
struct QueueNode*next;
};
struct Queue{
struct QueueNode*front;
struct QueueNode*tail;
};
void QueueInit(Queue* ps){
ps->front=ps->tail=NULL;
return ;
}
void QueueEmpty(Queue* ps){
assert(ps);
return ps->front==NULL;
}
void pushQueue(Queue* ps,int elem){
assert(ps);
Queuenode* newnode=(Queuenode*)malloc(sizeof(Queuenode));
if(!newnode){
return ;
}
else{
Queeunode->date=elem;
Queuenode->next=NULL;
}
Queue->head==NULL?Queue->tail=newnode:Queue->tail=newnode,Queue->tail=Queue->tail->next;
return ;
}
void popQueue(Queue* ps){
assert(ps);
queuenode* next=NULL;
ps->front->next==NULL?(ps->tail=ps->front=NULL):(next=ps->head->next,free(ps->head),ps->head=next);
}
}
int Numqueue(Queue* ps){
queuenode* p=ps->head;
int num=0;
while(p){
num++;
p=p->next;
}
return num;
}