linux C 单向链表(无头和有头结点)

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

typedef struct student{
	int num;
	struct student *next;
}student;

#define NODE_SIZE sizeof(struct student)


/****************************************************
 *	函数功能:创建链表
 *	函数参数:无
 *	函数输出:头指针
*****************************************************/
static struct student* create_list()
{
	struct student* head=NULL;	/* 指向第一个节点的头指针 */
	struct student* p1=NULL;	/* 用于新建的节点 */
	struct student* p2=NULL;	/* 用于指向最后一个节点 */
	p1 = (struct student*)malloc(NODE_SIZE);
	
	/* 开始时都指向新申请的第一个节点 */
	head = p2 = p1;
	
	scanf("%d", &p1->num); /* 对新节点数据域进行赋值 */
	
	/* 如果输入不为0,则新建节点 */
	while( p1->num != 0)
	{

		p1 = (struct student*)malloc(NODE_SIZE);
		scanf("%d", &p1->num);
		p2->next = p1;
		p2 = p1;
	}
	p2->next = NULL;
	return head;
}
/****************************************************
 *	函数功能:遍历链表中每一个数据域
 *	函数参数:head头指针
 *	函数输出:无
*****************************************************/
void show_list(struct student* head)
{
	struct student* p = head;
	while (p != NULL)
	{
		printf("%d\n", p->num);
		p = p ->next;

	}
}

/****************************************************
 *	函数功能:计算链表的元素个数
 *	函数参数:head头指针
 *	函数输出:元数个数
*****************************************************/
int how_maney(struct student** head)
{
	struct student* p = *head;
	int iCount = 0;
	
	while (p!=NULL)
	{
		p = p->next;
		++iCount;
	}
	return iCount;

}

/****************************************************
 *	函数功能:指定位置插入节点
 *	函数参数:head头指针,index插入位置,num插入节点的值
 *	函数输出:指定位置节点的值
*****************************************************/
static int insert_list(struct student** head, int index, int num)
{
	int iCount = how_maney(head);

	/*  新申请的待插入节点 */
	struct student* p = (struct student*)malloc(sizeof(struct student));
	p->num = num;
	/* index == 1,则在第一个节点前插入 */
	if (index == 1)
	{
		p->next = *head;
		*head = p;
		return (*head)->num;
	}
	else if (index > iCount)/* 说明在链表尾部插入节点 */
	{
		struct student* p1 = *head;
		while (p1->next != NULL)
		{
			p1 = p1->next;
		}
		p1->next = p;
		p->next = NULL;
		return iCount;
		
	}
	else	/* 在中间位置插入新节点 */
	{
		struct student* p1 = *head;
		int i = 1;
		while (p1!=NULL && i < index-1)
		{
			p1 = p1->next;
			++i;
		}
		p->next = p1->next;
		p1->next = p;
		return i;

	}
	return -1;
}
/****************************************************
 *	函数功能:删除指定位置节点
 *	函数参数:head头指针,index插入位置,num插入节点的值
 *	函数输出:指定位置节点的值
*****************************************************/
static void delete_list(struct student** head, int index)
{
	struct student* p = *head;
	struct student* p1 = NULL;
	int iCount = how_maney(head);
	/* 首先判断删除是否为头结点 */
	if(index == 1)	
	{	
		printf("删除第一个节点\n");
		*head = (*head)->next;
		free(p);
		return ;
	}
	else if (index >= iCount ) /* 如果删除的是尾部节点 */
	{
		int i = 1;
		printf("删除尾部节点\n");

		/* 找到要删除的前一个节点 */
		while(p != NULL && i < iCount-1)
		{
			p = p->next;
			i++;
		}
		/* 释放节点空间 */
		free(p->next);
		p->next = NULL; 
		return ;
	}
	else /* 删除的是中间节点 */
	{
		
		int i = 1;
		printf("删除中间节点\n");

		while (p!= NULL && i < index-1)
		{
			p = p->next;
			++i;
		}
		p1 = p->next;
		p->next = p1->next;
		free(p1);
		return ;
	}
	
	return ;
}
int main()
{
	struct student* head = NULL;
	struct student* node;
	head = create_list(node);
	printf("bbbb\n");
	show_list(head);
	printf("aaaa\n");
	
	printf("链表元素个数:%d\n", how_maney(&head));

	/*insert_list(&head, 1, 100);
	show_list(head);
	printf("链表元素个数:%d\n", how_maney(&head));
	
	delete_list(&head, 3);
	show_list(head);
	printf("链表元素个数:%d\n", how_maney(&head));
	*/
	
	
	return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//有头结点的单向链表
typedef struct MyNode{
    int num;
    struct MyNode *next;
}STNode_def;

#define NODE_SIZE sizeof(STNode_def)
#define SUCCESS 0
#define FAILURE -1


//链表初始化
STNode_def* list_init()
{
    STNode_def* head_ptr = (STNode_def*)malloc(NODE_SIZE);  /* 指向第一个节点的头指针 */
    
    if (head_ptr == NULL)
    {
        perror("malloc");
        return NULL;
    }
    
    memset(head_ptr, 0x00, NODE_SIZE);
    
    head_ptr->next = NULL;
    return head_ptr;
}

//遍历链表中每一个数据域
void list_print(STNode_def* head)
{
    STNode_def* p = head->next;
    while (p != NULL)
    {
        printf("%d ", p->num);
        p = p ->next;
    }

	printf("\n");
}


//链表的元素个数
int list_size(STNode_def* head)
{
    STNode_def* p = head;
    int size = 0;
    
    while (p->next != NULL)
    {
        p = p->next;
        size++;
    }

    return size;
}

//尾插入
int list_push_back(STNode_def* head, int value)
{
    STNode_def* p = head; //头结点的下一个节点
    STNode_def* pnew_node = (STNode_def*)malloc(NODE_SIZE);
    if (pnew_node == NULL)
    {
        printf("param is null\n");
        return FAILURE;
    }
    
    memset(pnew_node, 0x00, sizeof(NODE_SIZE));
    pnew_node->num = value;
    while (p->next != NULL)
    {
        p = p->next;
    }

    p->next = pnew_node;
    pnew_node->next = NULL;
    return SUCCESS;
}

//头插入
int list_push_front(STNode_def* head, int value)
{
    //STNode_def* p = head;
    STNode_def* pnew_node = (STNode_def*)malloc(NODE_SIZE);
    if (pnew_node == NULL)
    {
        printf("param is null\n");
        return FAILURE;
    }
    
    memset(pnew_node, 0x00, sizeof(NODE_SIZE));
    pnew_node->num = value;

    pnew_node->next = head->next;   //没有元素时,pnew_node->next = NULL也符合;
    head->next = pnew_node;
    
    return SUCCESS;
}


//尾删
void list_pop_back(STNode_def* head)
{
    STNode_def* p = head;
    
    int size = list_size(head);
    int cnt = 0;
    
    //找到需要删除结点的前驱结点
    while(p->next != NULL && cnt < size-1)
    {
        cnt++;
        p = p->next;
    }
    
    free(p->next);      //释放删除结点
    p->next = NULL;
}



//头删
void list_pop_front(STNode_def* head)
{
    STNode_def* p = head->next;
    
    if (head->next != NULL)
    {
        head->next = head->next->next; //找到删除结点的后驱结点
        free(p);
    }
}

//反转链表,使用结点的指针指向反转,最后将尾结点赋值给head->next
void list_reverse(STNode_def* head)
{
    int size = list_size(head);
    if (size <= 1)
    {
        return;
    }

    STNode_def *p = head->next;
    STNode_def *ppre = head->next;
    STNode_def *ptemp = NULL;
    while(p != NULL)
    {
        ptemp = p->next;
        if (head->next == p)
        {
            ppre = NULL;
        }
        p->next = ppre;
        ppre = p;
        p = ptemp;
    }
    head->next = ppre;
}


void swap(int *var1, int *var2)
{
    int temp = *var1;
    *var1 = *var2;
    *var2 = temp;
}

//链表元素排序flag:真为递增,假为递减
void list_sort(STNode_def* head, int flag)
{
    STNode_def* p = NULL;
    STNode_def* q = NULL;
    
    for (p =head->next; p->next != NULL; p = p->next)
    {
        for (q=head->next; q->next != NULL; q = q->next)
        {
            if (flag)
            {
                if (q->num > q->next->num)
                {
                    swap(&(q->num), &(q->next->num));
                }
            }
            else 
            {
                if (q->num < q->next->num)
                {
                    swap(&(q->num), &(q->next->num));
                }
            }
            
        }
    }
}
//释放链表
void list_destory(STNode_def* head)
{
	STNode_def* p = head;
	STNode_def* p_tmp = NULL;
	while(p != NULL)
	{
		p_tmp = p;
		p = p->next;
		free(p_tmp);
	}
}
int main()
{
    STNode_def* head = list_init();
    int i = 0;
    for (i=0; i<10; i++)
    {
        list_push_back(head, i);
    }

    list_sort(head, 1);
    printf("size:%d\n", list_size(head));
    list_print(head);

	
	list_destory(head);
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值