单链表

1、头插法、尾插法

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

typedef struct node Node;
typedef Node * Link; // 指针

void insert_head_node(Link newnode, Link *head)
{
    newnode->next = *head;
    *head = newnode;
}

void insert_tail_node(Link newnode, Link *head)//二级指针
{
    if(*head == NULL)
    {
        newnode->next = NULL;
	    *head = newnode;
    }
    else
    {
        Link temp = *head;
	    while(temp->next != NULL)
	    {
	        temp = temp->next;
	    }
	    temp->next = newnode;
	    newnode->next = NULL;
    }
}

2、单链表操作源码

#include "LinkList.h"
#include <stdlib.h>
#include <stdio.h>
//带头结点链表
int LinkInit(Node **l)
{
	*l = (Node *)malloc(sizeof(Node) * 1);   //分配头结点   l 就是头指针
	if (NULL == *l)
	{
		return FAILURE;
	}

	(*l)->next = NULL;    //头结点指针域为空
	return SUCCESS;
}

//插入结点
//头指针、插入的位置、插入的元素的值
int LinkInsert(Node *l, int n, ElemType e)  //n 插入的位置
{
	Node *p = l;
	int k = 0;   //k 移动的次数

	if (NULL == l)
	{
		return FAILURE;
	}

//从指向头结点的位置开始,循环几次就移几次,就指向第几个元素
	while (k < n-1 && p != NULL)//循环n-1次,指针p指向第n-1个元素
	{
		p = p->next;//p指针后移一个
		k++;
	}
    //最终k的值其实为n-1,所以总共移动了n-1次

	if (k > n || p == NULL) //
	{
		return FAILURE;
	}

	Node *q = (Node *)malloc(sizeof(Node) * 1);// 申请空间
	if (NULL == q)
	{
		return FAILURE;
	}

	q->data = e;   //数据域
	q->next = p->next;//后继
	p->next = q;//前驱

	return SUCCESS;
}

//头指针、函数指针
int LinkTraverse(Node *l, void (*p)(ElemType)) //遍历
{
	if (NULL == l)
	{
		return FAILURE;
	}
	Node *q = l;

	while (q->next)
	{
		q = q->next;
		p(q->data);//打印
	}

	return SUCCESS;
}

//传参:头指针L
//返回值:成功则返回链表长度,反之FAILURE
int LinkLength(Node *l) //求链表长度Length
{
	if (NULL == l) //入参判断
	{
		return FAILURE;
	}

	int len = 0;
	Node *p = l->next; // p指向第一个结点

	while (p) //每次p指向一个结点,再判断p是否为空,不为空则len加1
	{
		len++;
		p = p->next;//P指针后移,指向下一个结点
	}

	return len;
}

//传参:头指针L
//返回值:TRUE or FALSE
int LinkEmpty(Node *l)//判断链表是否为空
{
	return (l->next == NULL) ? TRUE : FALSE;
}

//传参:头指针L、获取元素所在的位置P、变量e的地址(e用来保存元素的值)
//返回值:FAILURE or SUCCESS
int GetElem(Node *l, int p, ElemType *e)    //p 位置
{
	if (NULL == l || p < 1)   //入参判断  p不能小于0
	{
		return FAILURE;
	}

	Node *q = l;
	int i;

	for (i = 0; i < p && q != NULL; i++)    //循环p次,同时满足q不为空
	{
		q = q->next;
	}

	if (!q)      //如果q为空,说明p(位置)大于长度
	{
		return FAILURE;
	}

	*e = q->data;     //q已经指向第p个结点

	return SUCCESS;
}

int LocateElem(Node *l, ElemType e, int (*p)(ElemType, ElemType))
{//定位一个元素
	if (NULL == l)
	{
		return FAILURE;
	}
	
	Node *q = l;
	int len = 0;//

	while (q->next)//先判断q->next是否为空,不为空len就加1,q指针后移
	{
		len++;
		q = q->next;
		if (p(e, q->data) == TRUE)
		{
			return len;
		}
	}
	return FAILURE;
}

int LinkDelete(Node *l, int p, ElemType *e)//删除第p个结点
{
	int k = 0;
	Node *q = l;//q指向头结点

	if (l == NULL)
	{
		return FAILURE;
	}

	while (k < p-1 && q != NULL)//循环p-1次,最后指针q指向第p-1个结点,即要删除的结点的前一个
	{
		q = q->next;
		k++;
	}

	if (k > p || q == NULL)
	{
		return FAILURE;
	}

	Node *n = q->next;//用n保存第p个结点的指向,便于后面free
	*e = n->data;
	q->next = n->next;//改变指向
	free(n);//释放空间
	return SUCCESS;
}

int LinkClear(Node *l)
{
	if (NULL == l)
	{
		return FAILURE;
	}

	Node *p = l->next;

	while (p)
	{
		l->next = p->next;//跳过一个第一个结点
		free(p);//释放第一个结点
		p = l->next;//p再次指向新的第一个结点
	}
	return SUCCESS;
}

int LinkDestroy(Node **l)
{
	if (l == NULL)
	{
		return FAILURE;
	}
	free(*l);
	(*l) = NULL;
	return SUCCESS;
}

//逆序
int LinkReverse(Node *l)
{
	if (NULL == l)
	{
		return FAILURE;
	}

	Node *p = l->next;//p指向第一个结点
	l->next = NULL;//头结点指针域置空

	while (p != NULL)
	{
		Node *q = p;
		p = p->next;
		q->next = l->next;
		l->next = q; 
	}
	return SUCCESS;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值