链表C语言和C++两种方式实现

一、C语言版本链表:

方向1:无表头

        法一:尾插法

#include
#include
//打印 创建 释放 删除某个数 插入某个数 (T_T)5个功能
struct Node
{
	int data;
	struct Node* next;
};
typedef struct Node Node;

void print(Node* head);
Node* creat();
void release(Node* head);
Node* Delete(Node* head, int num);
Node* Insert(Node* head, int num);

int main()
{
	int num;
	int num2;//需要插入的数

	Node* head;
	head = creat();
	printf("\n");
	print(head);
	printf("\n");

	printf("请输入你要删除:\n");
	scanf_s("%d",& num);
	head=Delete(head, num);
	print(head);
	printf("\n");
	printf("请输入你要插入的数字:\m");
	scanf_s("%d", &num2);

	release(head);
	return 0;
}

//创建链表函数,返回值为head指针
//动态申请
Node* creat()
{
	//值得令人注意的是typedef的*无法将后面都改成指针类型
	int num;
	Node* p, * head = NULL, * tailor = NULL;//注意先初始化为0
	scanf_s("%d", &num);//以输入的数字为-999为终止条件
	while (num != -999)
	{
		p = (Node*)malloc(sizeof(Node));
		p->data = num;
		p->next = NULL;//容易忘
		if (head == NULL)
		{
			head = p;
		}
		else
		{
		 tailor->next=p;//保证p是尾插进去的,指向最后一个
		}
		tailor = p;//更新tailor
		scanf_s("%d", &num);
	}
	return (head);
}

void print(Node* head)
{
	Node* p = head;
	if (p == NULL)
	{
		printf("空链表\n");
	}
	else
	{
		printf("链表如下:\n");
		while (p != NULL)
		{
			printf("%5d", p->data);
			p = p->next;
		}
	}
}
void release(Node* head)
{
	Node* p1=head, *p2;//释放需要定义两个工作指针!!!!
	while (p1 != NULL)
	{
		p2=p1;//p2用来释放
		p1 = p1->next;//p1更加靠前
		free(p2);
	}
	printf("释放成功!!!!");
}
Node* Delete(Node* head, int num)
{
	Node* p1, * p2=NULL;//两个工作指针
	if (NULL == head)
	{
		printf("该链表为air链表!!");
		return (head);
	}

	p1 = head;
	while (p1->next && p1->data != num)//定位!同时保证p2在p1后面
	{
		p2 = p1;
		p1 = p1->next;
	}
	if (p1->data == num)
	{
		if (p1 == head)
		{
			head = p1->next;
		}
		else
		{
			p2->next = p1->next;
		}
		free(p1);
		printf("\n释放成功!");
	}
	else
	{
		printf("删除失败");
	}
	return head;
}
//在有序链表从小到大存放的前提下
Node* Insert(Node* head, int num)//插入数据num
{
	Node* p, * p1, * p2=NULL;//同样的,两个工作指针
	p = (Node*)malloc(sizeof(Node));
	p->data = num;
	p->next = NULL;

	p1 = head;
	while (p1->next && p->data > p1->data)//定位
	{
		p2 = p1;
		p1 = p1->next;
	}

	if (p1 == head)
	{
		p1->next = head;
		head = p1;
	}
	else
	{
		p2->next = p;
		p->next = p1;
	}
	printf("数据插入成功!!!");

	return head;
}

        法二:前插法

#include
#include

struct Node
{
	int data;
	struct Node* next;
};
typedef struct Node Node;

void print(Node* head);
Node* creat();
void release(Node* head);


int main()
{
	Node* head;
	head = creat();
	printf("\n");
	print(head);
	release(head);
	return 0;
}

//创建链表函数,返回值为head指针
//动态申请
//前插法
Node* creat()
{
	//值得令人注意的是typedef的*无法将后面都改成指针类型
	int num;
	Node* p, *head = NULL, *tail = NULL;
	scanf_s("%d", &num);//以输入的数字为-999为终止条件
	while (num != -999)
	{
		p = (Node*)malloc(sizeof(Node));
		p->data = num;
		p->next = NULL;//容易忘
		if (tail == NULL)
		{
			tail= p;
		}
		else
		{
			p->next=head;
		}
		head= p;//更新head
		scanf_s("%d", &num);
	}
	return (head);
}

void print(Node* head)
{
	Node* p = head;
	if (p == NULL)
	{
		printf("空链表\n");
	}
	else
	{
		printf("链表如下:\n");
		while (p != NULL)
		{
			printf("%5d", p->data);
			p = p->next;
		}
	}
}
void release(Node* head)
{
	Node* p1 = head, * p2;
	while (p1 != NULL)
	{
		p2 = p1;
		p1 = p1->next;
		free(p2);
	}
	printf("释放成功!!!!");
}

 方向二:有表头

        方法:前插法

#include
#include

using namespace std;
struct Node
{
	int data;
	Node* next;
};
Node* creatList()
{
	Node* headNode = new Node;
	headNode->next = nullptr;
	return headNode;
}
Node* creatNode(int data)
{
	Node* node = new Node;
	node->data = data;
	node->next = nullptr;
	return node;
}
void insertData(Node*headNode,int data)
{
	Node* newNode = creatNode(data);
	newNode->next = headNode->next;
	headNode->next = newNode;
}
void printList(Node* headNode)
{
	Node* pMove = headNode->next;//注意:表头是不用打印的。
	while (pMove != nullptr)
	{
		cout << pMove->data << "\t";
		pMove = pMove->next;
	}
}
void testList()
{
	Node* list = creatList();//创建链表表头。
	insertData(list, 10);
	insertData(list, 13);
	insertData(list, 21);
	insertData(list, 666);
	printList(list);
}
int main()
{
	testList();
	return 0;
}

二、C++版本链表

推荐Node用struct,无需考虑权限写接口的问题

#include

using namespace std;
struct Node
{
	int data;
	Node* next;
};
class List
{
public:
	void creatList()
	{
		headNode = new Node;
		headNode->next = nullptr;
	}
	void creatNode(int data) //有表头前插法
	{
		Node* newNode = new Node;
		newNode->data = data;
		newNode->next = headNode->next;
		headNode->next = newNode;
	}
	void printList()
	{
		Node* pMove = new Node;
		pMove = headNode->next;//注意头结点不算,要指向下一个
		while (pMove != nullptr)
		{
			cout << pMove->data << "  ";
			pMove = pMove->next;
		}
	}
protected:
	Node* headNode;
};
void testList()
{
	List list;
	list.creatList();
	list.creatNode(3);
	list.creatNode(2);
	list.creatNode(1);
	list.printList();
}
int main()
{
	testList();
	return 0;
}

此间出了一个bug:链表C语言和C++两种方式实现_第1张图片

 不能写Node* headNode=new Node; 否则就变成了局部变量,在下面print和insert中headNode就属于为初始化的状态,会报错!

你可能感兴趣的:(C++,链表,c语言,c++)