线性表
一、顺序存储
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
typedef struct Student
{
char name[20];
char sex;
float score;
}Student;
typedef struct Array
{
Student* ptr;
size_t cap;
size_t cnt;
}Array;
Array* create_array(size_t cap)
{
Array* arr = malloc(sizeof(Array));
arr->ptr = malloc(sizeof(Student)*cap);
arr->cap = cap;
arr->cnt = 0;
return arr;
}
void destroy_array(Array* arr)
{
free(arr->ptr);
free(arr);
}
bool insert_array(Array* arr,int index,const Student* stu)
{
if(arr->cnt >= arr->cap || index < 0 || index >= arr->cap)
return false;
for(int i=arr->cnt; i>index; i--)
{
arr->ptr[i] = arr->ptr[i-1];
}
arr->ptr[index] = *stu;
arr->cnt++;
return true;
}
bool delete_array(Array* arr,int index)
{
if(0 > index || index >= arr->cnt)
return false;
for(int i=index; i<arr->cnt; i++)
{
arr->ptr[i] = arr->ptr[i+1];
}
arr->cnt--;
return true;
}
bool modify_array(Array* arr,int index,Student* stu)
{
if(0 > index || index >= arr->cnt)
return false;
arr->ptr[index] = *stu;
return true;
}
int query_array(Array* arr,Student* key)
{
for(int i=0; i<arr->cnt; i++)
{
if(!strcmp(arr->ptr[i].name,key->name) &&
arr->ptr[i].sex == key->sex &&
arr->ptr[i].score == key->score)
return i;
}
return -1;
}
int sort_array(Array* arr)
{
for(int i=0; i<arr->cnt-1; i++)
{
int m = i;
for(int j=i+1; j<arr->cnt; j++)
{
if(arr->ptr[m].score > arr->ptr[j].score)
m = j;
}
if(m != i)
{
Student tmp = arr->ptr[m];
arr->ptr[m] = arr->ptr[i];
arr->ptr[i] = tmp;
}
}
}
Student* max_array(Array* arr)
{
int max = 0;
for(int i=1; i<arr->cnt; i++)
{
if(arr->ptr[max].score < arr->ptr[i].score)
max = i;
}
return arr->ptr+max;
}
Student* min_array(Array* arr)
{
int min = 0;
for(int i=1; i<arr->cnt; i++)
{
if(arr->ptr[min].score > arr->ptr[i].score)
min = i;
}
return arr->ptr+min;
}
void merge_array(Array* arr1,Array* arr2)
{
arr1->cap += arr2->cap;
arr1->ptr = realloc(arr1->ptr,sizeof(Student)*arr1->cap);
for(int i=0; i<arr2->cnt; i++)
{
arr1->ptr[arr1->cnt++] = arr2->ptr[i];
}
}
void show_array(Array* arr)
{
for(int i=0; i<arr->cnt; i++)
{
printf("%s %s %g\n",
arr->ptr[i].name,
arr->ptr[i].sex=='w'?"女":"男",
arr->ptr[i].score);
}
printf("\n");
}
int main(int argc,const char* argv[])
{
Array* arr = create_array(10);
Student stu = {"heheA"};
for(int i=0; i<10; i++)
{
stu.name[4] += 1;
stu.sex = rand()%2 ? 'w' : 'm';
stu.score = (rand()%9000+1000)/100.0;
insert_array(arr,i,&stu);
}
show_array(arr);
printf("%d\n",query_array(arr,&stu));
Student* p = min_array(arr);
printf("max stu = %s %s %g\n",
p->name,
p->sex == 'w' ? "女" : "男",
p->score);
sort_array(arr);
show_array(arr);
Array* arr2 = create_array(5);
Student stus[5] = {
{"xixi1",'w',99},
{"xixi2",'m',98},
{"xixi3",'w',97},
{"xixi4",'m',96},
{"xixi5",'w',95},
};
insert_array(arr2,0,stus+0);
insert_array(arr2,0,stus+1);
insert_array(arr2,0,stus+2);
insert_array(arr2,0,stus+3);
insert_array(arr2,0,stus+4);
show_array(arr2);
merge_array(arr,arr2);
show_array(arr);
return 0;
}
二、链式存储(单向)
1.不带头结点
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define TYPE int
typedef struct ListNode
{
TYPE data;
struct ListNode* next;
}ListNode;
ListNode* create_node(TYPE data)
{
ListNode* node = malloc(sizeof(ListNode));
node->data = data;
node->next = NULL;
return node;
}
void head_add_list(ListNode** head,TYPE data)
{
ListNode* node = create_node(data);
if(NULL == *head)
{
*head = node;
return;
}
node->next = *head;
*head = node;
}
void tail_add_list(ListNode** head,TYPE data)
{
ListNode* node = create_node(data);
if(NULL == *head)
{
*head = node;
return;
}
ListNode* tail = *head;
while(NULL != tail->next)
tail = tail->next;
tail->next = node;
}
bool insert_list(ListNode** head,int index,TYPE data)
{
if(0 > index)
return false;
if(0 == index)
{
head_add_list(head,data);
return true;
}
ListNode* prev = *head;
while(--index && NULL != prev)
{
prev = prev->next;
}
if(NULL == prev)
return false;
ListNode* node = create_node(data);
node->next = prev->next;
prev->next = node;
}
bool head_del_list(ListNode** head)
{
if(NULL == *head)
return false;
ListNode* tmp = *head;
*head = (*head)->next;
free(tmp);
return true;
}
bool tail_del_list(ListNode** head)
{
if(NULL == *head)
return false;
ListNode* prev = *head;
while(NULL != prev->next->next)
{
prev = prev->next;
}
free(prev->next);
prev->next = NULL;
return true;
}
bool index_del_list(ListNode** head,int index)
{
if(0 > index)
return false;
if(0 == index)
return head_del_list(head);
ListNode* prev = *head;
while(--index && NULL != prev->next)
{
prev = prev->next;
}
printf("%p\n",prev);
if(NULL == prev->next)
return false;
ListNode* tmp = prev->next;
prev->next = tmp->next;
free(tmp);
return true;
}
void show_list(ListNode* head)
{
for(ListNode* n=head; n!=NULL; n=n->next)
{
printf("%d ",n->data);
}
printf("\n");
}
int main(int argc,const char* argv[])
{
ListNode* head = NULL;
for(int i=0; i<5; i++)
{
tail_add_list(&head,i);
}
show_list(head);
index_del_list(&head,6);
show_list(head);
return 0;
}
2.带头结点
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define TYPE int
typedef struct ListNode
{
TYPE data;
struct ListNode* next;
}ListNode;
ListNode* create_node(TYPE data)
{
ListNode* node = malloc(sizeof(ListNode));
node->data = data;
node->next = NULL;
return node;
}
typedef struct List
{
ListNode* head;
ListNode* tail;
size_t size;
}List;
List* create_list(void)
{
List* list = malloc(sizeof(List));
list->head = create_node(0);
list->tail = list->head;
list->size = 0;
return list;
}
void head_add_list(List* list,TYPE data)
{
ListNode* node = create_node(data);
if(list->tail == list->head)
list->tail = node;
node->next = list->head->next;
list->head->next = node;
list->size++;
}
void tail_add_list(List* list,TYPE data)
{
ListNode* node = create_node(data);
if(list->tail == list->head)
list->head->next = node;
list->tail->next = node;
list->tail = node;
list->size++;
}
bool insert_list(List* list,int index,TYPE data)
{
if(0 > index || index >= list->size)
return false;
ListNode* prev = list->head;
while(index--)
prev = prev->next;
ListNode* node = create_node(data);
node->next = prev->next;
prev->next = node;
list->size++;
return true;
}
bool head_del_list(List* list)
{
if(list->head == list->tail)
return false;
ListNode* tmp = list->head->next;
list->head->next = tmp->next;
free(tmp);
if(1 == list->size--)
list->tail = list->head;
return true;
}
bool tail_del_list(List* list)
{
if(list->head == list->tail)
return false;
ListNode* prev = list->head;
while(list->tail != prev->next)
prev = prev->next;
prev->next = NULL;
free(list->tail);
list->tail = prev;
list->size--;
return true;
}
bool index_del_list(List* list,int index)
{
if(0 > index || index >= list->size)
return false;
ListNode* prev = list->head;
while(index--)
prev = prev->next;
ListNode* tmp = prev->next;
prev->next = tmp->next;
free(tmp);
list->size--;
if(tmp == list->tail)
list->tail = prev;
return true;
}
ListNode* query_list(List* list,TYPE key)
{
for(ListNode* n=list->head->next; n!=NULL; n=n->next)
{
if(n->data == key)
return n;
}
return NULL;
}
ListNode* access_list(List* list,int index)
{
if(0 > index || index >= list->size)
return NULL;
ListNode* node = list->head->next;
while(index--)
node = node->next;
return node;
}
bool modify_index_list(List* list,int index,TYPE data)
{
ListNode* node = access_list(list,index);
if(NULL == node)
return false;
node->data = data;
return true;
}
bool modify_value_list(List* list,TYPE old,TYPE data)
{
ListNode* node = query_list(list,old);
if(NULL == node)
return false;
node->data = data;
return true;
}
void sort_list(List* list)
{
for(ListNode* i=list->head->next; i->next!=NULL; i=i->next)
{
ListNode* m=i;
for(ListNode* j=i->next; j!=NULL; j=j->next)
{
if(m->data > j->data)
m = j;
}
if(m != i)
{
TYPE tmp = m->data;
m->data = i->data;
i->data = tmp;
}
}
}
void merge_list(List* l1,List* l2)
{
l1->tail->next = l2->head->next;
l1->tail = l2->tail;
l1->size += l2->size;
l2->head->next = NULL;
l2->tail = l2->head;
l2->size = 0;
}
ListNode* max_list(List* list)
{
if(list->head == list->tail)
return NULL;
ListNode* max = list->head->next;
for(ListNode* n=max->next; n!=NULL; n=n->next)
{
if(n->data > max->data)
max = n;
}
return max;
}
ListNode* min_list(List* list)
{
if(list->head == list->tail)
return NULL;
ListNode* min = list->head->next;
for(ListNode* n=min->next; n!=NULL; n=n->next)
{
if(n->data < min->data)
min = n;
}
return min;
}
void show_list(List* list)
{
for(ListNode* n=list->head->next; n!=NULL; n=n->next)
{
printf("%d ",n->data);
}
printf("\n");
}
int main(int argc,const char* argv[])
{
List* list = create_list();
for(int i=0; i<10; i++)
{
tail_add_list(list,i);
}
index_del_list(list,9);
tail_add_list(list,666);
modify_index_list(list,0,999);
modify_index_list(list,10,6666);
modify_value_list(list,1234,777);
sort_list(list);
show_list(list);
printf("max %d\n",max_list(list)->data);
printf("min %d\n",min_list(list)->data);
return 0;
}
三、双向链表
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define TYPE int
typedef struct DoubleListNode
{
struct DoubleListNode* prev;
TYPE data;
struct DoubleListNode* next;
}DoubleListNode;
DoubleListNode* create_node(TYPE data)
{
DoubleListNode* node = malloc(sizeof(DoubleListNode));
node->prev = NULL;
node->data = data;
node->next = NULL;
return node;
}
typedef struct DoubleList
{
DoubleListNode* head;
DoubleListNode* tail;
size_t size;
}DoubleList;
DoubleList* create_list(void)
{
DoubleList* list = malloc(sizeof(DoubleList));
list->head = create_node(0);
list->tail = create_node(0);
list->size = 0;
list->head->next = list->tail;
list->tail->prev = list->head;
return list;
}
void _add_list(DoubleListNode* prev,DoubleListNode* next,DoubleListNode* node)
{
node->next = next;
node->prev = prev;
prev->next = node;
next->prev = node;
}
void _del_list(DoubleListNode* node)
{
node->prev->next = node->next;
node->next->prev = node->prev;
free(node);
}
void head_add_list(DoubleList* list,TYPE data)
{
_add_list(list->head,list->head->next,create_node(data));
list->size++;
}
void tail_add_list(DoubleList* list,TYPE data)
{
_add_list(list->tail->prev,list->tail,create_node(data));
list->size++;
}
bool head_del_list(DoubleList* list)
{
if(0 == list->size)
return false;
_del_list(list->head->next);
list->size--;
return true;
}
bool tail_del_list(DoubleList* list)
{
if(0 == list->size)
return false;
_del_list(list->tail->prev);
list->size--;
return true;
}
DoubleListNode* index_list(DoubleList* list,int index)
{
if(0 > index || index >= list->size)
return NULL;
DoubleListNode* node;
if(index < list->size/2)
{
node = list->head->next;
while(index--)
node = node->next;
}
else
{
node = list->tail->prev;
while(++index < list->size)
node = node->prev;
}
return node;
}
bool index_add_list(DoubleList* list,int index,TYPE data)
{
DoubleListNode* node = index_list(list,index);
if(NULL == node)
return false;
_add_list(node->prev,node,create_node(data));
list->size++;
return true;
}
bool index_del_list(DoubleList* list,int index)
{
DoubleListNode* node = index_list(list,index);
if(NULL == node)
return false;
_del_list(node);
list->size--;
return true;
}
DoubleListNode* query_list(DoubleList* list,TYPE key)
{
for(DoubleListNode* n=list->head->next; n!=list->tail; n=n->next)
{
if(n->data == key)
return n;
}
return NULL;
}
bool value_del_list(DoubleList* list,TYPE data)
{
DoubleListNode* node = query_list(list,data);
if(NULL == node)
return false;
_del_list(node);
list->size--;
return true;
}
bool modify_index_list(DoubleList* list,int index,TYPE data)
{
DoubleListNode* node = index_list(list,index);
if(NULL == node)
return false;
node->data = data;
return true;
}
bool modify_value_list(DoubleList* list,TYPE old,TYPE data)
{
DoubleListNode* node = query_list(list,old);
if(NULL == node)
return false;
node->data = data;
return true;
}
void sort_list(DoubleList* list)
{
for(DoubleListNode* i=list->head->next; i!=list->tail; i=i->next)
{
TYPE value = i->data;
DoubleListNode* j = i;
while(j->prev!=list->head && value < j->prev->data)
{
j->data = j->prev->data;
j=j->prev;
}
j->data = value;
}
}
void merge_list(DoubleList* l1,DoubleList* l2)
{
l2->head->next->prev = l1->tail->prev;
l1->tail->prev->next = l2->head->next;
l1->tail->prev = l2->tail->prev;
l2->tail->prev->next = l1->tail;
l2->head->next = l2->tail;
l2->tail->prev = l2->head;
l1->size += l2->size;
l2->size = 0;
}
DoubleListNode* max_list(DoubleList* list)
{
if(0 == list->size)
return NULL;
DoubleListNode* max = list->head->next;
for(DoubleListNode* n = max->next; n!=list->tail; n=n->next)
{
if(n->data > max->data)
max = n;
}
return max;
}
DoubleListNode* min_list(DoubleList* list)
{
if(0 == list->size)
return NULL;
DoubleListNode* min = list->head->next;
for(DoubleListNode* n = min->next; n!=list->tail; n=n->next)
{
if(n->data < min->data)
min = n;
}
return min;
}
void show_list(DoubleList* list)
{
printf("正序:");
for(DoubleListNode* n=list->head->next; n!=list->tail; n=n->next)
{
printf("%d ",n->data);
}
printf("\n倒序:");
for(DoubleListNode* n=list->tail->prev; n!=list->head; n=n->prev)
{
printf("%d ",n->data);
}
printf("\n");
}
void clear_list(DoubleList* list)
{
while(head_del_list(list));
}
void destroy_list(DoubleList* list)
{
clear_list(list);
free(list->head);
free(list->tail);
free(list);
}
int main(int argc,const char* argv[])
{
DoubleList* l1 = create_list();
DoubleList* l2 = create_list();
for(int i=0; i<10; i++)
{
tail_add_list(l1,i);
tail_add_list(l2,10+i);
}
show_list(l1);
show_list(l2);
merge_list(l1,l2);
show_list(l1);
DoubleListNode* max = max_list(l1);
if(NULL != max)
printf("max = %d\n",max->data);
clear_list(l1);
clear_list(l2);
show_list(l1);
show_list(l2);
destroy_list(l1);
destroy_list(l2);
return 0;
}