数据结构_Day05

双向链表的增删改查

main.c

#include"head.h"

int main(int argc, const char* argv[])
{
	pointer_DouLink_node head = create_DouLink_head();
	int len;//插入字符串的个数
	int pos;
	printf("请输入插入字符串的个数:");
	scanf("%d", &len);
	datatype data;
	//头插
	for(int i = 0; i<len; i++)
	{
		printf("请输入字符串(头插):");
		scanf(" %s", data);
		insert_DouLink_head(head, data);
	}
	output_DouLink(head);
	//尾插
	for(int i = 0; i<len; i++)
	{
		printf("请输入字符串(尾插):");
		scanf(" %s", data);
		insert_DouLink_rear(head, data);
	}
	output_DouLink(head);

//
	printf("头删一个结点\n");
	delete_DouLink_head(head);
	output_DouLink(head);
	// printf("%d\n", head->len);

//
	printf("尾删一个结点\n");
	delete_DouLink_rear(head);
	output_DouLink(head);
	// printf("%d\n", head->len);
	
	//按位置插入
	printf("请输入要插入的位置:");
	scanf("%d", &pos);
	printf("请输入字符串:");
	scanf(" %s", data);
	insert_DouLink_pos(head, pos, data);
	output_DouLink(head);
	//按位置修改
	printf("请输入要修改的位置:");
	scanf("%d", &pos);
	printf("请输入字符串:");
	scanf(" %s", data);
	update_DouLink_pos(head, pos, data);
	output_DouLink(head);
	//按位置删除
	printf("请输入要删除的位置:");
	scanf("%d", &pos);
	delete_DouLink_pos(head, pos);
	output_DouLink(head);
	//按位置查找
	printf("请输入要查找的位置:");
	scanf("%d", &pos);
	search_DouLink_pos(head, pos);
	output_DouLink(head);
	
	return 0;
}

fun.c

#include"head.h"

/*
 * function:	双向链表创建头结点
 * @param [void] 
 * @return      成功返回结点地址,失败返回NULL
 */
pointer_DouLink_node create_DouLink_head(void)
{
    //
    pointer_DouLink_node node = (pointer_DouLink_node)malloc(sizeof(struct Node));
    if(NULL == node)
    {
        return NULL;
    }
    node->len = 0;
    node->next = NULL;
    node->prev = NULL;

    return node;
}
/*
 * function:	双向链表创建普通结点
 * @param [void] 
 * @return      成功返回结点地址,失败返回NULL
 */
pointer_DouLink_node create_DouLink_node(void)
{
    //
    pointer_DouLink_node node = (pointer_DouLink_node)malloc(sizeof(struct Node));
    if(NULL == node)
    {
        return NULL;
    }
    strcpy(node->data, "");
    node->next = NULL;
    node->prev = NULL;

    return node;
}
/*
 * function:	双向链表遍历(双向)
 * @param [head] 头结点指针
 * @return      void
 */
void output_DouLink(pointer_DouLink_node head)
{
    // printf("dbg-进入output_DouLink:\n");
    if(NULL == head || 0 == head->len)
    {
        // printf("dbg-NULL == head || 0 == head->len\n");
        return;
    }
    pointer_DouLink_node p = head;
    // printf("向后挨个输出:\n");
    while(NULL != p->next)
    {
        p = p->next;
        printf("%s\t", p->data);
    }
    printf("\n");
    // printf("向前挨个输出:\n");
    while(NULL != p->prev)
    {
        printf("%s\t", p->data);
        p = p->prev;
    }
    printf("\n");

}
/*
 * function:	双向链表头插
 * @param [head] 头结点指针
 * @param [data] 要插入的数据
 * @return      成功返回0, 失败返回-1
 */
int insert_DouLink_head(pointer_DouLink_node head, datatype data)
{
    pointer_DouLink_node node_new = create_DouLink_node();
    if(NULL == node_new)
    {
        return -1;
    }
    //数据域
    strcpy(node_new->data, data);
    // 指针域
    node_new->prev = head;
    node_new->next = head->next;
    //如果不是第一个结点,则需要将 后继结点的prev 指向新结点
    //注意,这一句要写在更新头结点指针之前
    if (head->next != NULL)
    {
        head->next->prev = node_new;
    }
    //更新头结点指针
    head->next = node_new;
    //更新长度
    head->len++; 

    return 0;
}
/*
 * function:	双向链表尾插
 * @param [head] 头结点指针
 * @param [data] 要插入的数据
 * @return      成功返回0, 失败返回-1
 */
int insert_DouLink_rear(pointer_DouLink_node head, datatype data)
{
    // printf("dbg-enter insert_DouLink_rear\n");
    //定义新结点
    pointer_DouLink_node node_new = create_DouLink_node();
    if(NULL == node_new || NULL == head)
    {
        // printf("dbg-NULL == node_new || NULL == head\n");
        return -1;
    }
    //创建遍历指针
    pointer_DouLink_node p = head;
    //循环遍历到最后一个结点
    while(NULL!=p->next)
    {
        p = p->next;
        // printf("dbg-in while\n");
    }
    // printf("dbg-after while\n");
    //将新值赋给新结点
    strcpy(node_new->data, data);
    //新结点指针赋值
    node_new->prev = p;
    //前后结点指针赋值
    p->next = node_new;
    //更新长度
    head->len++;
    return 0;
}
/*
 * function:	双向链表头删
 * @param [head] 头结点指针
 * @return      成功返回0, 失败返回-1
 */
int delete_DouLink_head(pointer_DouLink_node head)
{
    //前提判断head不为空,长度不为0
    if(0 == head->len || NULL == head)
    {
        printf("删除失败\n");
        return -1;
    }
    //创建结点指针,保存要删去的结点指针
    pointer_DouLink_node p = head->next;
    //更新头结点的后继指针
    head->next = p->next;//若只剩p指向的结点,p->next中为空,也可以进行赋值
    //若删去后还剩普通结点,则将剩余结点的前驱指针更新
    if(p->next != NULL)
    {
        p->next->prev = head;
    }
    //释放空间
    free(p);
    p = NULL;
    //长度--
    head->len--;
    return 0;

}
/*
 * function:	双向链表尾删
 * @param [head] 头结点指针
 * @return      成功返回0, 失败返回-1
 */
int delete_DouLink_rear(pointer_DouLink_node head)
{
    //前提判断head不为空,长度不为0
    if(0 == head->len || NULL == head)
    {
        printf("删除失败\n");
        return -1;
    }
    
    //创建结点指针,遍历到倒数第二个结点
    pointer_DouLink_node p = head;
    while(NULL != p->next->next)
    {
        p = p->next;
    }
    //free
    free(p->next);
    //连接
    p->next = NULL;
    head->len--;
    return 0;
}
/*
 * function:	双向链表按位置插入
 * @param [head] 头结点指针
 * @param [pos] 要插入的位置
 * @param [data] 要插入的数据
 * @return     成功返回0, 失败返回-1 
 */
int insert_DouLink_pos(pointer_DouLink_node head, int pos, datatype data)
{
    //前提判断
    if(NULL == head || pos<1 || pos>head->len+1)
    {
        printf("插入失败!\n");
        return -1;
    }
    //定义一个新指针,指向要插入的位置之前一个结点
    pointer_DouLink_node p = head;
    //从0开始,到pos-2结束,(pos-1次)
    //循环执行第1次,p就指向第1个结点
    for(int i = 0; i<pos-1; i++)
    {
        p = p->next;
    }
    //申请新结点
    pointer_DouLink_node newnode = create_DouLink_node();
    if(NULL == newnode)
    {
        return -1;
    }
    strcpy(newnode->data, data);
    newnode->prev = p;
    newnode->next = p->next;
    //注意,如果pos不是最后一个结点的后继位置,需要将后继结点的前驱指针指向新结点。
    //如果pos是最后一个结点的后继位置,插入时不需要后继节点的前驱指针
    if(NULL != p->next)
    {
        p->next->prev = newnode;
    }
    p->next = newnode;
    head->len++;
    return 0;
}
/*
 * function:	双向链表按位置修改
 * @param [head] 头结点指针
 * @param [pos] 要修改的位置
 * @param [data] 新数据
 * @return      成功返回0, 失败返回-1
 */
int update_DouLink_pos(pointer_DouLink_node head, int pos, datatype data)
{
    //前提判断
    if(NULL == head || pos<1 || pos>head->len)
    {
        printf("修改失败!\n");
        return -1;
    }
    //定义一个新指针,指向要修改的位置
    pointer_DouLink_node p = head;
    //从0开始,到pos-1结束,(pos次)
    //循环执行第1次,p就指向第1个结点
    for(int i = 0; i<pos; i++)
    {
        p = p->next;
    }
    strcpy(p->data, data);
    return 0;
}
/*
 * function:	双向链表按位置删除
 * @param [head] 头结点指针
 * @param [pos] 要删除的位置
 * @return      成功返回0, 失败返回-1
 */
int delete_DouLink_pos(pointer_DouLink_node head, int pos)
{
    if(NULL == head || pos<1 || pos>head->len)
    {
        printf("删除失败\n");
        return -1;
    }
    //申请结点指针
    pointer_DouLink_node p = head;
    //p指向要删除结点的前一个结点
    for(int i = 0; i<pos-1; i++)
    {
        p = p->next;
    }
    //del指向要删除的结点,即第pos个结点
    pointer_DouLink_node del = p->next; 
    p->next = del->next;
    if(NULL != del->next)
        del->next->prev = p;
    free(del);
    head->len--;
}
/*
 * function:	双向链表按位置查找
 * @param [head] 头结点指针
 * @param [pos] 要查找的位置
 * @return      成功返回0, 失败返回-1
 */
int search_DouLink_pos(pointer_DouLink_node head, int pos)
{
    if(NULL == head || pos<1 || pos>head->len)
    {
        printf("查找失败\n");
        return -1;
    }
    pointer_DouLink_node p = head;
    for(int i = 0; i<pos; i++)
    {
        p = p->next;
    }
    printf("您要查找的是:%s\n", p->data);
}



head.h

#ifndef __HEAD_H__
#define __HEAD_H__
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define MAXSIZE 7

typedef char datatype[20]; //链表数据类型

typedef struct Node //结构体名可以为空
{
	union
	{
		datatype data;  //数据域
		int len;	//头结点中的链表长度
	};
	struct Node* next;	//指针域,指向下一个结点的地址
	struct Node* prev;	//指针域,指向上一个结点的地址
} * pointer_DouLink_node;  //pointer_DouLink_node为结构体指针类型

/*
 * function:	双向链表创建头结点
 * @param [void] 
 * @return      成功返回结点地址,失败返回NULL
 */
pointer_DouLink_node create_DouLink_head(void);
/*
 * function:	双向链表创建普通结点
 * @param [void] 
 * @return      成功返回结点地址,失败返回NULL
 */
pointer_DouLink_node create_DouLink_node(void);
/*
 * function:	双向链表遍历(双向)
 * @param [head] 头结点指针
 * @return      void
 */
void output_DouLink(pointer_DouLink_node head);
/*
 * function:	双向链表头插
 * @param [head] 头结点指针
 * @param [data] 要插入的数据
 * @return      成功返回0, 失败返回-1
 */
int insert_DouLink_head(pointer_DouLink_node head, datatype data);
/*
 * function:	双向链表尾插
 * @param [head] 头结点指针
 * @param [data] 要插入的数据
 * @return      成功返回0, 失败返回-1
 */
int insert_DouLink_rear(pointer_DouLink_node head, datatype data);
/*
 * function:	双向链表头删
 * @param [head] 头结点指针
 * @return      成功返回0, 失败返回-1
 */
int delete_DouLink_head(pointer_DouLink_node head);
/*
 * function:	双向链表尾删
 * @param [head] 头结点指针
 * @return      成功返回0, 失败返回-1
 */
int delete_DouLink_rear(pointer_DouLink_node head);
/*
 * function:	双向链表按位置插入
 * @param [head] 头结点指针
 * @param [pos] 要插入的位置
 * @param [data] 要插入的数据
 * @return     成功返回0, 失败返回-1 
 */
int insert_DouLink_pos(pointer_DouLink_node head, int pos, datatype data);
/*
 * function:	双向链表按位置修改
 * @param [head] 头结点指针
 * @param [pos] 要修改的位置
 * @param [data] 新数据
 * @return      成功返回0, 失败返回-1
 */
int update_DouLink_pos(pointer_DouLink_node head, int pos, datatype data);
/*
 * function:	双向链表按位置删除
 * @param [head] 头结点指针
 * @param [pos] 要删除的位置
 * @return      成功返回0, 失败返回-1
 */
int delete_DouLink_pos(pointer_DouLink_node head, int pos);
/*
 * function:	双向链表按位置查找
 * @param [head] 头结点指针
 * @param [pos] 要查找的位置
 * @return      成功返回0, 失败返回-1
 */
int search_DouLink_pos(pointer_DouLink_node head, int pos);
#endif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值