双链表的排序,合并

/*双向链表*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*基础操作*/

//1.定义
typedef int data_t; //错误1 分号忘了加
typedef struct node_t{
    data_t data;
    struct node_t *prior, *next; //错误2是struct node_t,而不是node_t

}dlinklist;

//2.创建表,初始化表
dlinklist *create_dlinklist()
{
    dlinklist *head = (dlinklist*)malloc(sizeof(dlinklist)); //malloc的用法不熟悉

    if(NULL == head) return NULL;
    head->data = -1;
    head->next = head->prior = NULL;

    return head;
}


//3.求表长
int get_len_dlinklist(dlinklist *head)
{
    int len = 0;
    if(NULL == head) return NULL;

    dlinklist *p = head->next;//错误是head.next 空表是只有头结点的表,头结点不算长度
    while(p != NULL) //错误是p!=NULL
    {
        len++;
        p = p->next;
    }
    return len;

}


//4.判空
int dlinklist_is_empty(dlinklist *head)
{
    if(NULL == head) return NULL;
    return ((head->next == head->prior)?1:0);
}

//5.打印
void show_dlinklist(dlinklist *head)
{
    if(NULL == head) return NULL;
    dlinklist *p = head->next;
    while(p != NULL)
    {
        printf("%d ",p->data);
        p = p->next;
    }
    printf("\n");
}

//6.清空链表
void clear_dlinklist(dlinklist *head)
{
    if(NULL == head) return NULL;
    dlinklist *p = head->next;
    dlinklist *q = NULL;
    head->next = NULL;
    while(p != NULL)
    {
        q = p->next;
        free(p);
        p = q; //p向后移一位
    }

}

//7.销毁链表??
int destory_dlinklist(dlinklist** head)
{
    free(*head);
    head = NULL; 
    return 0;
}


/*增删改查*/

//1.头插法
int insert_head_dlinklist(dlinklist* head, data_t val)
{
    if(NULL == head) return -1;
    //准备new 节点
    dlinklist *new  = (dlinklist *)malloc(sizeof(dlinklist));
    new->data = val; //
    new->next = NULL;
    new->prior = NULL;
    //头插法 插入
    if(head->next   == NULL)
    {
        new->next = head->next;
        new->prior = head;
        head->next = new; 
    }else
    {
        new->next = head->next;
        head->next->prior = new; 
        new->prior = head;
        head->next = new; 
    }
    return 0;
}




/*题目*/

//1.删除结点p

//找到结点p
dlinklist *get_node_dlinklist(dlinklist *head, int i)
{
    dlinklist *p = head->next;
    int j = 1;
    while (p != head && j < i)
    {
        p = p->next;
        j++;
    }
    while (p == head | j > i)
    {
        return -1;
    }
    return p;
}

int del_node_dlinklist(dlinklist *head, int i, data_t e)
{
    dlinklist *p = NULL;
    if(!(p = get_node_dlinklist(head,i))) return -1;
    e = p->data;
    p->prior->next = p->next;
    p->next->prior = p->prior;
    free(p);
    return 0;
}


//2.在p结点之后插入一个节点
int insert_dlinklist(dlinklist *head, int i, data_t e)
{
    dlinklist *p = NULL;
    if(!(p = get_node_dlinklist(head,i))) return -1;
    dlinklist *s = (dlinklist *)malloc(sizeof(dlinklist));
    s->data=e;
    s->next = p->next;
    s->prior = p;
    p->next->prior = s;
    p->next =s;
}

//3.逆序双向表
dlinklist *reverse(dlinklist *head)
{
 if(NULL == head || NULL == head->next)  return head;

    //指向首元结点
    dlinklist *first = head->next;
    
    //指向第二个节点
    dlinklist *second = first->next;

    //首元结点与后续节点断开
    first->next = NULL;

    dlinklist *third = NULL;

    while(second)
    {
       third = second->next;

       second->prior = NULL;
       second->next = first;
       first->prior = second;

       //使下一节点成为当前节点
       first = second;
       //继续循环
       second = third;

    }

  //将最后一个节点的前驱节点赋值为头结点指针
  first->prior = head;
  // 将头结点与后续节点连接
  head->next = first;
  return head;

}


//4.合并有序表?

dlinklist *merge(dlinklist *A, dlinklist *B)
{
	dlinklist *r, *t, *p, *q;
	r = A;
	p = r->next;
	r->next = NULL;
	p->prior = NULL;//断开连接,单独取出A的首元素
 
	t = B;
 
	//先将A中p所指剩余结点插入新链表中
	while (p != NULL)
	{
		//用q指向p的下一个结点
		q = p->next;
 
		//将p与新链表A中的结点比较有无相同值
		while (r != NULL)
		{
			if (r->data == p->data)
			{
				//若相同则删除p所指结点,取链表中下一个值
				free(p);
				break;
			}
			r = r->next;
		}
 
		if (r == NULL)//若无相同值
		{
			//将p结点插入到新链表中
			p->next = A->next;
			p->prior = A;
			if (A->next != NULL)
			{
				A->next->prior = p;
			}
			A->next = p;
		}
 
		p = q;
		r = A;
	}
 
 
	//先将B中t所指剩余结点插入新链表中
	r = A;
	while (t != NULL)
	{
		//用q指向t的下一个结点
		q = t->next;
 
		//将t与新链表A中的结点比较有无相同值
		while (r != NULL)
		{
			if (r->data == t->data)
			{
				//若相同则删除t所指结点,取链表中下一个值
				free(t);
				break;
			}
			r = r->next;
		}
 
		if (r == NULL)//若无相同值
		{
			//将p结点插入到新链表中
			t->next = A->next;
			t->prior = A;
			if (A->next != NULL)
			{
				A->next->prior = t;
			}
			A->next = t;
		}
 
		t = q;
		r = A;
	}
 
	return A;
}




//5.排序
dlinklist *sort_dlinklist(dlinklist *head)				  //函数返回值为头指针,形参也为头指针
{
	int i=0,j=0;
	int n= get_len_dlinklist(head);              //调用统计节点个数的函数
	dlinklist *p=head;                         //定义两个临时指针来进行数据处理
	dlinklist *pn=head;                        //p和pn总是两个相邻的节点,且pn在p之后
       //****冒泡排序****//
	for(i=0;i<n;i++)
	{
		p=head->next;
		pn=p->next;
		for(j=0;j<n-1-i;j++)
		{
			if(p->data  < pn->data)          //判断,条件成立之后交换位置
			{
				if(pn->next==NULL)           //判断是否为尾节点
				{
					//**交换位置代码**//
					p->next=pn->next;
					pn->prior=p->prior;
					pn->next=p;
					p->prior->next=pn;
					p->prior=pn;
					//**位置交换结束**//
				}
				else
				{
					//**交换位置代码**//
					p->next=pn->next;
					pn->prior=p->prior;
					pn->next->prior=p;
					p->prior->next=pn;
					//下一行请注意//	
					pn->next=p;
					p->prior=pn;
					//**位置交换结束**//
					pn=p->next;      //位置交换结束之后进行指针偏移,pn指向p的下一个节点
				}
            }
		    else                                       //条件不成立
            {
				p=p->next;
				pn=p->next;
					//如果未发生位置交换,则两个指针都要发生偏移
		    }
		
	    }
    }
	return head;		
}





int main(int argc, char *argv[])
{ 
    int a[6] = {1,3,5,7,9,11};
    int b[6] = {2,4,6,8,10,12};
    
    dlinklist* head1 = create_dlinklist();
    
    for(int i = 0; i < 6; i++)
    {
        insert_head_dlinklist(head1,a[6-i-1]);
    }
    printf("list1:");
    show_dlinklist(head1);

    
     dlinklist* head2 = create_dlinklist();
    for(int i = 0; i < 6; i++)
    {
        insert_head_dlinklist(head2,b[6-i-1]);
    }
    printf("list1:");
    show_dlinklist(head2);

    del_node_dlinklist(head1,2, 5); //删除的节点为第2位,从1开始数起
    show_dlinklist(head1);  

    insert_dlinklist(head1, 4, 98);
    show_dlinklist(head1); 

    reverse(head1);
    show_dlinklist(head1); 

    sort_dlinklist(head1);
    show_dlinklist(head1);


    merge(head1, head2);
    show_dlinklist(head1);
    sort_dlinklist(head1);
    show_dlinklist(head1);

    
    return 0;
} 

运行结果

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值