【链表】带头结点的双向循环链表

还需改进:

creat_node这个函数应有返回类型,来判断新建结点是否成功,不然主函数中不管成不成功都会访问该节点成员。

改了这个函数,在主函数中create_node后要判断是否成功,不成功就提示并退出函数,退出前别忘了还要释放链表!

同时create_link这个函数中也要判断head是否申请成功,不成功的话同样提示并退出函数。

#include 
#include 

struct dnode
{
    int num;

    struct dnode * prior;
    struct dnode * next;
};

typedef struct dnode Dnode;
typedef struct dnode * Dlink;

void create_dnode(Dlink *DblNode)
{
    int count = 10;

    do
    {
        *DblNode = (Dlink)malloc(sizeof(Dnode));
        count--;
    }while(!is_malloc_ok(*DblNode) && count);
}

int is_malloc_ok(Dlink DblNode)
{
    if(DblNode == NULL)
    {
        printf("malloc error!\n");
        return 0;
    }
    return 1;
}

void create_dlink(Dlink *DblHead)
{
    Dlink DblNode;
    create_dnode(&DblNode);

    *DblHead = DblNode;
    DblNode->next = DblNode;
    DblNode->prior= DblNode;
}

void insert_dnode_head(Dlink DblHead,Dlink DblNode)
{
    DblHead->next->prior = DblNode;
    DblNode->next = DblHead->next;
    DblHead->next = DblNode;
    DblNode->prior = DblHead;
}

void display(Dlink DblHead)
{
    if(DblHead == NULL)
    {
        printf("该链表已被释放\n");
        return;
    }

    Dlink p = DblHead;
    
    printf("该链表显示是:\n");
    if(p->next == DblHead)
    {
        printf("Link is empty!\n");
    }
    else
    {
        p = p->next;
        while(p != DblHead)
        {
            printf("num is %d\n",p->num);
            p = p->next;
        }
    }
}

int length(Dlink DblHead)
{
    Dlink p = DblHead->next;
    int count = 0;

    while(p != DblHead)
    {
        count++;
        p = p->next;
    }

    return count;
}

void insert_dnode_tail(Dlink DblHead,Dlink DblNode)
{
    DblNode->prior = DblHead->prior;
    DblHead->prior->next = DblNode;
    DblNode->next = DblHead;
    DblHead->prior = DblNode;
}

void insert_dnode_mid_before(Dlink DblHead,Dlink DblNode,int num)
{
    Dlink p = DblHead->next;

    while(p != DblHead && p->num != num)
    {
        p = p->next;
    }

    if(p == DblHead)
    {
        printf("No such node!\n");
    }
    else
    {
        DblNode->prior = p->prior;
        p->prior->next = DblNode;
        DblNode->next = p;
        p->prior = DblNode;
    }
}

void insert_dnode_mid_after(Dlink DblHead,Dlink DblNode,int num)
{
    Dlink p = DblHead->next;

    while(p != DblHead && p->num != num)
    {
        p = p->next;
    }

    if(p == DblHead)
    {
        printf("No such node!\n");
    }
    else
    {
        p->next->prior = DblNode;
        DblNode->next = p->next;
        p->next = DblNode;
        DblNode->prior = p;
    }
}

void delete_dnode(Dlink DblHead,int num)
{
    Dlink p = DblHead->next;

    while(p != DblHead && p->num != num)
    {
        p = p->next;
    }

    if(p == DblHead)
    {
        printf("No such node!\n");
    }
    else
    {
        p->next->prior = p->prior;
        p->prior->next = p->next;
        free(p);
    }
}

Dlink find(Dlink DblHead,int num)
{
    Dlink p = DblHead->next;

    while(p != DblHead && p->num != num)
    {
        p = p->next;
    }

    if(p == DblHead)
    {
        p = NULL;
        return p;
    }
    else
    {
        return p;
    }
}

void make_empty(Dlink DblHead)
{
    Dlink p = DblHead->next;
    Dlink q;

    while(p != DblHead)
    {
        q = p->next;
        p->next->prior = p->prior;
        p->prior->next = p->next;
        free(p);
        p = q;
    }
}

void release_dlink(Dlink *DblHead)
{
    make_empty(*DblHead);
    free(*DblHead);
    *DblHead = NULL;
}

int main()
{
    Dlink DblHead;
    Dlink DblNode;
    int i;
    int num;

    create_dlink(&DblHead);

    for(i = 0 ;i < 5; i++)
    {
        create_dnode(&DblNode);
        DblNode->num = i + 1;

        //insert_dnode_head(DblHead,DblNode);
        insert_dnode_tail(DblHead,DblNode);
    }

    display(DblHead);
    printf("该链表长度为%d\n\n",length(DblHead));


    create_dnode(&DblNode);
    printf("请输入你想插入的结点的数值:");
    scanf("%d",&DblNode->num);
    printf("请输入你想在值为哪个的结点前插入该结点:");
    scanf("%d",&num);

    insert_dnode_mid_before(DblHead,DblNode,num);

    display(DblHead);
    printf("该链表长度为%d\n\n",length(DblHead));


    create_dnode(&DblNode);
    printf("请输入你想插入的结点的数值:");
    scanf("%d",&DblNode->num);
    printf("请输入你想在值为哪个的结点后插入该结点:");
    scanf("%d",&num);

    insert_dnode_mid_after(DblHead,DblNode,num);

    display(DblHead);
    printf("该链表长度为%d\n\n",length(DblHead));

    
    printf("请输入你想删除的结点的数值:");
    scanf("%d",&num);

    delete_dnode(DblHead,num);
    
    display(DblHead);
    printf("该链表长度为%d\n\n",length(DblHead));

    
    printf("请输入你想查找的结点的数值:");
    scanf("%d",&num);

    DblNode = find(DblHead,num);
    if(DblNode == NULL)
    {
        printf("没有这个结点\n");
    }
    else
    {
        printf("这个结点的数值是%d\n\n",DblNode->num);
    }

    make_empty(DblHead);

    display(DblHead);
    printf("该链表长度为%d\n\n",length(DblHead));

    release_dlink(&DblHead);
    display(DblHead);
    
    

    return 0;
}

小练:

要注意的点:

  1. 前指针和后指针名字
  2. MakeEmpty函数我清空的时候并没有每删一个都保持环,所以最后一步要让head的prior指向head,不然再加node就会有错
  3. Display函数要判断一下头结点是否为空!空就是已经被释放了!这个也要注意别忘了
  4. Delete函数里也要注意删除指针的时候,前后两个节点有两根线要连,不要只连一个了
#include 
#include 

struct node
{
	int num;
	struct node *prior;
	struct node *next;
};

typedef struct node Node;
typedef struct node *Link;

int CreateNode(Link *new_node)
{
	*new_node = (Link)malloc(sizeof(Node));

	if(*new_node == NULL)
		return 0;
	return 1;
}

int CreateLink(Link *head)
{
	if(!CreateNode(head))
		return 0;

	(*head)->next = (*head);
	(*head)->prior = (*head);
	return 1;
}

void InsertHead(Link head, Link node)
{
	head->next->prior = node;
	node->next = head->next;
	head->next= node;
	node->prior = head;
}

void InsertTail(Link head, Link node)
{
	head->prior->next = node;
	node->prior = head->prior;
	head->prior = node;
	node->next = head;
}

void InsertBefore(Link head, Link node, int num)
{
	Link p = head->next;

	while(p != head)
	{
		if(p->num == num)
		{
			p->prior->next = node;
			node->prior = p->prior;
			node->next = p;
			p->prior = node;
			return;
		}
		p = p->next;
	}

	printf("Cannot find the node!\n");
}

void InsertAfter(Link head, Link node, int num)
{
	Link p = head->next;

	while(p != head)
	{
		if(p->num == num)
		{
			p->next->prior = node;
			node->next = p->next;
			p->next = node;
			node->prior = p;
			return;
		}
		p = p->next;
	}

	printf("Cannot find the node!\n");
}

void Delete(Link head, int num)
{
	Link p = head->next;

	while(p != head)
	{
		if(p->num == num)
		{
			p->prior->next = p->next;
			p->next->prior = p->prior;
			free(p);
			return;
		}
		p = p->next;
	}

	printf("Cannot find the node!\n");
}

void Display(Link head)
{
	Link p = head->next;

	if(p == head)
	{
		printf("Link is empty!\n");
		return;
	}

	while(p != head)
	{
		printf("num = %d\n", p->num);
		p = p->next;
	}
}

void MakeEmpty(Link head)
{
	Link p = head->next;

	while(p != head)
	{
		head->next = head->next->next;
		free(p);
		p = head->next;
	}

	head->prior = head;
}

void ReleaseLink(Link *head)
{
	MakeEmpty(*head);
	free(*head);
	*head = NULL;
}

int main()
{
	Link head;
	Link new_node;
	int i;

	CreateLink(&head);

	for(i = 0; i < 7; i++)
	{
		if(CreateNode(&new_node))
		{
			new_node->num = i + 1;
			InsertTail(head,new_node);
		}
	}

	Display(head);
	printf("\n");

	if(CreateNode(&new_node))
	{
		new_node->num = 23;
		InsertBefore(head,new_node,3);
	}

	Delete(head, 6);

	Display(head);
	printf("\n");

	MakeEmpty(head);

	for(i = 0; i < 7; i++)
	{
		if(CreateNode(&new_node))
		{
			new_node->num = i + 1;
			InsertTail(head,new_node);
		}
	}

	Display(head);
	printf("\n");

	ReleaseLink(&head);


	return 0;
}

 

你可能感兴趣的:(C,链表)