一、双向链表
(1)双向链表初始化函数
/*
* function: 双链表初始化函数
* @param [ in]
* @param [out]
* @return
*/
void doblinklist_init(doblinklist* head){
*head = (doblinklist)malloc(sizeof(struct node));
(*head)->prev = NULL;
(*head)->next = NULL;
(*head)->info.size = 0;
}
(2)双链表的头插函数
/*
* function: 双链表的头插函数
* @param [ in]
* @param [out]
* @return
*/
void doblinklist_headInsert(doblinklist head, datatype e){
doblinklist pnew_node = (doblinklist)malloc(sizeof(struct node));
if(NULL == pnew_node){
printf("malloc\n");
return;
}
pnew_node->info.data = e;
//修改next指针
pnew_node->next = head->next;
head->next = pnew_node;
//修改prev指针
pnew_node->prev = head;
if(head->next->next != NULL) //除开特殊情况,只有一个头结点
pnew_node->next->prev = head->next;
head->info.size++; //长度加一
return;
}
(3)双链表的尾插函数
/*
* function: 双链表的尾插函数
* @param [ in]
* @param [out]
* @return
*/
void doblinklist_tailInsert(doblinklist head, datatype e){
doblinklist pnew_node = (doblinklist)malloc(sizeof(struct node));
if(NULL == pnew_node){
printf("malloc\n");
return;
}
pnew_node->info.data = e;
//找到双链表的尾结点
doblinklist tail = head;
while(NULL != tail->next) tail = tail->next;
//修改next指针
tail->next = pnew_node;
pnew_node->next = NULL;
//修改prev指针
tail->next->prev = tail;
head->info.size++;
return;
}
(4)双链表的头删函数
/*
* function: 双链表的头删函数
* @param [ in]
* @param [out]
* @return
*/
datatype doblinklist_headdel(doblinklist head){
//判断双链表是否为空
if(NULL == head->next){
printf("双链表为空,无法头删除!!\n");
return (datatype)-1;
}
doblinklist tmp = head->next;
int res = tmp->info.data;
head->next = tmp->next;
if(head->next != NULL) //不是只有一个数据结点的双链表
tmp->next->prev = head;
free(tmp);
return res;
}
(5)双链表的尾删函数
/*
* function: 双链表的尾删函数
* @param [ in]
* @param [out]
* @return
*/
datatype doblinklist_taildel(doblinklist head){
if(NULL == head->next){
printf("双链表为空,无法尾删除\n");
return (datatype)-1;
}
doblinklist pcur = head;
while(pcur->next->next!= NULL) pcur = pcur->next;
doblinklist tmp = pcur->next;
pcur->next = tmp->next;
int res = tmp->info.data;
free(tmp);
return res;
}
(6)双链表的指定位置插入元素
/*
* function: 双链表的按位置插入
* @param [ in]
* @param [out]
* @return
*/
void doblinklist_indexInsert(doblinklist head, datatype e, int index){
//判断插入位置是否合法
if(index < 1 || index > head->info.size + 1){
printf("插入位置不合法\n");
return;
}
doblinklist pnew_node = (doblinklist)malloc(sizeof(struct node));
if(NULL == pnew_node){
printf("malloc\n");
return;
}
pnew_node->info.data = e;
//找到插入位置的前驱结点
doblinklist pcur = head;
while(--index) pcur = pcur->next;
//插入结点,先修改next指针
pnew_node->next = pcur->next;
pcur->next = pnew_node;
//修改prev指针
pnew_node->prev = pcur;
if(pnew_node->next != NULL) //if(pcur->next != NULL) //段错误,我上面动了pcur的next现在指向的是pnew_node
pnew_node->next->prev = pcur;
head->info.size++;
return;
}
(7)双链表的指定位置删除元素
/*
* function: 双链表的按位置删除
* @param [ in]
* @param [out]
* @return
*/
datatype doblinklist_indexDel(doblinklist head, int index){
//判断删除的位置是否合法
if(index < 1 || index > head->info.size){
printf("删除位置不合法");
return (datatype)-1;
}
//判断双链表是否为空
if(NULL == head->next){
printf("双链表为空,无法删除\n");
return (datatype)-1;
}
//找到删除位置的前驱结点
doblinklist pcur = head;
while(--index) pcur = pcur->next;
//备份被删除结点
doblinklist tmp = pcur->next;
int res = tmp->info.data;
//删除结点,先修改next指针
pcur->next = tmp->next;
//修改prev指针
if(NULL != tmp->next) //排除特殊情况只有一个有效数据结点
tmp->next->prev = pcur;
free(tmp);
head->info.size--;
return res;
}
(8)双链表遍历函数
/*
* function: 双链表的遍历函数
* @param [ in]
* @param [out]
* @return
*/
void doblinklist_traverse(doblinklist head){
if(NULL == head->next){ //此时双链表为空
printf("双链表为空!!!\n");
return;
}
doblinklist pcur = head->next;
for(; pcur != NULL; pcur = pcur->next){
printf("%3d", pcur->info.data);
}
putchar(10);
}
二、顺序栈
(1)栈的初始化函数
/*
* function: 初始化一个空栈
* @param [ in]
* @param [out]
* @return
*/
seq_Stack stack_init(void){
seq_Stack st = (seq_Stack)malloc(sizeof(struct stack));
if(NULL == st){
printf("malloc\n");
return NULL;
}
st->top = -1;
return st;
}
(2)判断栈满
/*
* function: 判断栈满
* @param [ in]
* @param [out]
* @return
*/
int stack_isFull(seq_Stack st){
return st->top == MAXSIZE -1 ? 1:0;
}
(3)判断空栈
/*
* function: 判断栈空
* @param [ in]
* @param [out]
* @return
*/
int stack_isEmpty(seq_Stack st){
return st->top == -1;
}
(4)压栈函数
/*
* function: 压栈
* @param [ in]
* @param [out]
* @return
*/
void push(seq_Stack st, datatype e){
//判断栈满
if(stack_isFull(st)){
printf("栈满,不能压栈\n");
return;
}
st->top++;
st->arr[st->top] = e;
}
(5)弹栈函数
/*
* function: 弹栈
* @param [ in]
* @param [out]
* @return
*/
datatype pop(seq_Stack st){
//判断栈空
if(stack_isEmpty(st)){
printf("栈空,不能弹栈\n");
return (datatype)-1;
}
return st->arr[st->top--];
}
(6)遍历栈
/*
* function: 遍历栈
* @param [ in]
* @param [out]
* @return
*/
void stack_travser(seq_Stack st){
if(stack_isEmpty(st)){
printf("栈空!!!\n");
return;
}
int cur = st->top;
printf("stack element: ");
for(; cur >= 0; cur--){
printf("%-3d", st->arr[cur]);
}
printf("\n");
}
(7)获取栈顶元素
/*
* function: 获取栈顶元素
* @param [ in]
* @param [out]
* @return
*/
datatype stack_getTop(seq_Stack st){
if(stack_isEmpty(st)){
printf("栈空,无法获取栈顶元素\n");
return (datatype)-1;
}
return st->arr[st->top];
}
(8)销毁栈
/*
* function: 销毁栈
* @param [ in]
* @param [out]
* @return
*/
void stack_deInit(seq_Stack st){
st->top = -1;
free(st);
}
三、顺序队列
(1)顺序队列初始化函数
/*
* function: 创建一个空的顺序队列
* @param [ in]
* @param [out]
* @return
*/
sequeue* sequeue_init(void){
sequeue* sq = (sequeue*)malloc(sizeof(sequeue));
sq->front = sq->rear =0;
return sq;
}
(2)顺序队列判空
/*
* function: 判断队列是否为空
* @param [ in]
* @param [out]
* @return 队列为空返回1, 队列不为空返回0
*/
int sequeue_isEmpty(sequeue* sq){
return sq->rear == sq->front ? 1:0;
}
(3)顺序队列判满
/*
* function: 判断队列是否为满(牺牲一个存储单元)
* @param [ in]
* @param [out]
* @return 队列为满返回1, 队列不为满返回0
*/
int sequeue_isFull(sequeue* sq){
return (sq->rear + 1) % MAXSIZE == sq->front ? 1:0;
}
(4)顺序队列出队
/*
* function: 顺序队列出队函数
* @param [ in]
* @param [out]
* @return
*/
datatype delQueue(sequeue* sq){
//判断队列是否为空
if(sequeue_isEmpty(sq)){
printf("队列为空,无法继续出队\n");
return (datatype)-1;
}
int res = sq->arr[sq->front];
sq->front = (sq->front + 1) % MAXSIZE;
return res;
}
(5)顺序队列入队
/*
* function: 顺序队列入队
* @param [ in]
* @param [out]
* @return
*/
void enQueue(sequeue* sq, datatype e){
//判断队列是否为满
if(sequeue_isFull(sq)){
printf("队列满,无法继续入队\n");
return;
}
sq->arr[sq->rear] = e;
sq->rear = (sq->rear + 1) % MAXSIZE;
return;
}
(6)获取循环队列长度
/*
* function: 获取循环队列长度
* @param [ in]
* @param [out]
* @return
*/
int sequeue_getLength(sequeue* sq){
return (sq->rear - sq->front + MAXSIZE ) % MAXSIZE;
}
(7)遍历循环队列
/*
* function: 遍历循环队列
* @param [ in]
* @param [out]
* @return
*/
void sequeue_traverse(sequeue* sq){
//判空
if(sequeue_isEmpty(sq)){
printf("队列为空!!!\n");
return;
}
for(int i = sq->front; i != sq->rear; i = (i + 1) % MAXSIZE){
printf("%-3d", sq->arr[i]);
}
putchar(10);
}
四、链式队列
(1)初始化空的链式队列
/*
* function: 初始化空的链式队列
* @param [ in]
* @param [out]
* @return
*/
QueueOp* linkqueue_init(){
//申请堆空间,该堆空间用于存储链表的头结点和尾结点地址
//即堆空间中只有front 和 rear
QueueOp* op = (QueueOp*)malloc(sizeof(QueueOp));
op->front = (linkqueue*)malloc(sizeof(linkqueue));
op->front->msg.size = 0;
op->front->next = NULL;
op->rear = op->front;
return op;
}
(2)链式队列入队---即单链表的尾插
/*
* function: 链式队列入队,即尾插
* @param [ in]
* @param [out]
* @return
*/
void linkqueue_enQueue(QueueOp* op, datatype e){
linkqueue* pnew_node = (linkqueue*)malloc(sizeof(linkqueue));
if(NULL == pnew_node){
printf("malloc\n");
return;
}
pnew_node->next = NULL;
pnew_node->msg.data = e;
//尾插--->找到尾结点
pnew_node->next = op->rear->next;
op->rear->next = pnew_node;
//更新尾结点
op->rear = pnew_node;
op->front->msg.size++;
return;
}
(3)链式队列出队---即单链表的头删除
/*
* function: 链式队列出队,即链表头删
printf("delqueue:%d\n", linkqueue_delQueue(op));
* @param [ in]
* @param [out]
* @return
*/
datatype linkqueue_delQueue(QueueOp* op){
if(op->front == op->rear){
printf("链队为空,无法删除\n");
return (datatype)-1;
}
linkqueue* tmp = op->front->next;
op->front->next = tmp->next;
datatype res = tmp->msg.data;
if(NULL == op->front->next) //特殊情况当只有一个数据结点,此时头删之后,rear指针应更新
op->rear = op->front;
free(tmp);
op->front->msg.size--;
return res;
}
(4)链式队列的遍历
/*
* function: 链式队列遍历
* @param [ in]
* @param [out]
* @return
*/
void linkqueue_traverse(QueueOp* op){
//链队判空
if(op->front == op->rear){
printf("队列为空!!!\n");
return;
}
linkqueue* pcur = op->front->next;
while(pcur){
printf("%-3d", pcur->msg.data);
pcur = pcur->next;
}
putchar(10);
}