数据结构-单链表

这是作业,本人菜鸡,大佬绕道

单链表的相关操作;

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define overflow 1
typedef struct node_{
	int data;
	struct node_ *next;
}Node,*node;
void initList(node &l);
void insertNode(node &l,int n);
void clearList(node &l);
void desList(node &l);
bool listEmpty(node &l);
int getElement(node &l,int i);
int locateElement(node &l,int e);
int priorElement(node &l,int e);
int nextElement(node &l,int e);
void deleteNode(node &l,int e);
void test();
//建立链表
void initList(node &l){
	l=(node)malloc(sizeof(Node));
	l->next=NULL;
	if (!l){
		exit(overflow);
	}
}
//插入元素 
void insertElement(node &l,int n,int g){
     node p,q;
     p=l;
	for (int i = 0; i < g; i ++) {
		p = p->next;
		if (p == NULL) {
			printf("The position %d is beyond the scope of the list.", g);
			return;
		}
	}
	q = (node)malloc(sizeof(Node));
    q->data = g;
	q->next = p->next;
	p->next = q;
	}
//尾插法
void insertNode(node &l,int n){
    if(n<0){
		printf("输入的n不合法\n");
		exit(overflow);
	}
	node last=NULL;
	last=l;
	for (int i=0;i<n;i++){
		node p=(node)malloc(sizeof(Node));
		scanf("%d",&p->data);
		p->next=NULL;
		last->next=p;
		last=p;		
	}
}
//打印链表
void printList(node &l)
{
	if (!l)
	{
		printf("链表不存在");
		exit(overflow);
	}
	printf("打印链表:");
	for (node p=l->next;p;p=p->next)
	{
		printf("%d ",p->data);
	}
	printf("\n"); 
}
//清空链表 
void clearList(node &l)
{
	node p=l->next;
	node q=p;
	while(p){
		q=p->next;
		free(p);
		p=NULL;
		p=q;
	}
	l->next=NULL; 
}
//销毁链表
void desList(node &l){
    node p=l;
	node q=p;
	while(p->next){
		q=p->next;
		free(p);
		p=NULL;
		p->next=q->next;
}
l=NULL;
printf("链表已销毁");}
 
//检查链表是否为空
bool listEmpty(node &l)
{
	if (l->next)
	{
		return true;
	}
	else
	{
		return false;
	}
}
//返回链表第i个的值
int getElement(node &l,int i){
    if (i<=0 || l->next==NULL){
		printf("链表为空或i的值不合法");
		exit(overflow);
	}
	node p=l;
	for (int q=0;q<i;q++)
	{
		p=p->next;
	}
    return p->data;
}
//返回与e值相同的元素位置
int locateElement(node &l,int e){
	int i=0;
	for (node p=l->next;p;p=p->next)
	{
		i++;
		if (p->data==e){
			return i;
		}
	}
    return 0;
}
//返回指定元素的前驱
int priorElement(node &l,int e){
	for (node p=l->next->next;p->next;p=p->next)
	{
		if (p->next->data==e){
			return p->data;
		}
	}
	return 0;
}
//返回指定元素的后继
int nextElement(node &l,int e)
{
	for (node p=l->next;p->next;p=p->next)
	{
		if (p->data==e){
			return p->next->data;
		}
	}
	return 0;
}
//删除指定的结点
void deleteNode(node &l,int e){
	node p=l;
	while(p->next) 
	{
		if (p->next->data==e){
			node q=p->next;
			p->next=p->next->next;
			free(q);
			q=NULL; 
		}
		else 
		p=p->next;
	}
}
void test(){
	node l;
	initList(l);
	int n;
	scanf("%d",&n);
	insertNode(l,n);
	printList(l);
	bool r=listEmpty(l);
	printf("链表是否为空:%d\n",r);
	int e;
	e=locateElement(l, 2);
	printf("该元素的位置:%d\n",e);
    e=getElement(l,3);
	printf("某位置的元素:%d\n",e);
	e=priorElement(l,e);
	printf("元素的前驱:%d\n",e);
	e=nextElement(l,e);
	printf("元素后继:%d\n",e);
	deleteNode(l,e);
	printf("删除指定元素后:");
	printList(l);
	clearList(l);
	r=listEmpty(l);
	printf("清空链表后:");
	printf("链表是否为空:%d\n",r);
	desList(l);
}
int main(void)
{
	test();
	return 0;
}

运行结果:

 总结:

链表的操作还是比较简单,但是我在内存和地址方面的理解很不好,这是我在几次作业中都表现出来的问题,一旦涉及new,delete,free就经常会出问题,这也是以前写代码从来不考虑内存方面的后果。

另外本次也有一些发现:首先free只是将指针所指的地址回收,其实质上还在,但不受保护,为避免相关麻烦(出过几次问题)最好同时将该指针置空

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是使用C语言实现的链表原地逆转的代码: ```c #include <stdio.h> #include <stdlib.h> struct Node { int data; struct Node* next; }; void reverseList(struct Node** head) { struct Node* prev = NULL; struct Node* current = *head; struct Node* next = NULL; while (current != NULL) { next = current->next; current->next = prev; prev = current; current = next; } *head = prev; } void printList(struct Node* head) { while (head != NULL) { printf("%d ", head->data); head = head->next; } printf("\n"); } void push(struct Node** headRef, int newData) { struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->data = newData; newNode->next = *headRef; *headRef = newNode; } int main() { struct Node* head = NULL; push(&head, 3); push(&head, 2); push(&head, 1); printf("Original list: "); printList(head); reverseList(&head); printf("Reversed list: "); printList(head); return 0; } ``` 在上述代码中,我们首先定义了一个 `Node` 结构体来表示链表中的每个节点,包括节点的值和指向下一个节点的指针。然后我们定义了 `reverseList` 函数来实现原地逆转链表的功能。该函数接受一个指向指针的指针 `head`,这是因为我们需要通过指针来修改链表的头节点,所以我们传递指向指针的指针。在函数内部,我们使用三个指针 `prev`、`current` 和 `next` 来依次遍历链表,并将每个节点的指针指向前一个节点,从而实现原地逆转链表的目的。 最后,我们定义了一个 `push` 函数来添加新节点到链表的头部,并定义了 `printList` 函数来打印链表中所有节点的值。在 `main` 函数中,我们创建了一个包含三个节点的链表,并调用 `reverseList` 函数来原地逆转该链表,最后打印出原始和逆转后的链表

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值