双向链表、顺序栈、顺序队列、链式队列实现函数

一、双向链表

(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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值