算法————笔试内容-->链表(一)

链表是一种基本的数据结构,每个数据项中都包含我们所需的到达下一个数据项的信息。链表比数组的优势在于,它可以提供高效的重排数据项的能力。


链表是一组数据项的集合,其中每个数据项都是一个节点的一部分,每个节点都包含指向下一个节点的连接。


链表中的末尾节点约定:

1.将其置为不指向任何节点的为空连接

2.使其指向一个不包含元素节点的为亚元节点

3.使其指向第一个节点(首节点),使链表成为循环链表


高效使用链表结构,内存分配时重要因素。无论何时,只要需要一个新的节点,就需要创建一个节点结构体的实例,并为它保留一定的内存。

如: link x = malloc(sizeof *x); 


数组中对应的插入和删除操作不方便,因为需要移动数组中受到影像数据项后的所有元素。

题目一:编程实现一个单链表的建立---测试---打印。

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

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

//创建链表
node* creat(){
	node *head,*p,*s; //创建节点指针
	int x,cycle=1;
	head = (node*) malloc(sizeof(node));//创建一个node将head指针指向他
	p=head;//将head地址赋给p
	//开始循环创建单向链表
	while(cycle){
		printf("\nplease input the data:");//输入单向链表中想存入的数据
		scanf("%d",&x);//接收输入的数据
		//如果输入的数据不为零则开始核心的创建单向链表的核心程序
		if(x!=0){
			s=(node*) malloc(sizeof(node));//分配一个node节点,将s指向他
			s->data=x;//修改创建新的节点中存储的值
			p->next=s;//将原始p->next指针指向创建新的节点的地址
			p=s;//将原始p指向新的节点处,反复重复上述过程就会创建一个新的单向链表
		}
		else cycle = 0;//循环推出的条件
	}
	//创建完想要的单向链表之后,要处理头和尾部的指针完成单向链表的定义
	head=head->next;
	p->next=NULL;
	return (head);
}

int length(node *head){
	int n=0;
	node *p;
	p=head;
	while(p!=NULL){
		p=p->next;
		n++;
	}
	return n;
}

//打印节点
void print_node(node *head){
	node *p ;
	int n;
	n = length(head);
	printf("\n now,These %d records are:\n",n);//打印出长度
	p=head;
	if(head!=NULL){
		//开始遍历单向列表
		while(p!=NULL){
			printf("\n uuu %d   ",p->data);
			p=p->next;
		}
	}
}
//主体测试函数
int main(){
	node *head;
	head = creat();
	int n = length(head);
	print_node(head);
	system("PAUSE");
	return 0;
}

试题二:编程实现单向链表的节点删除、插入。

//删除节点,删除节点的条件是否符合指定删除的内容值
node* remove_node(node* head,int num){
	node *p,*s;
	p = head;//从头开始遍历
	//快速需找指定的节点位置,针对指定删除内容不再首部和尾部的处理方式
	while(num!=p->data && p->next!=NULL){
		s = p;//s指针其实是保留原上一个节点的位置
		p = p->next;//p指针指向下一个
	}
	//搜索到了相应的数据,准备删除,但是要考虑首尾删除的问题
	if(num ==p->data){
		if(p==head){
			head = p->next;
			free(p);//注意要删除不用的内容,腾出内存
			printf("你所删除的节点为首部\n");
		}else{
			s->next = p->next;
			free(p);
			printf("你所删除的节点为中间部分\n");
		}
	}else
		printf("没有找到指定的节点\n");
	return head;
}
<pre name="code" class="cpp">//插入节点,可以自己默认从头插入或从尾插入或者指定一个顺序插入,本实例代码是按照一个顺序进行插入
node* insert_node(node* head,int num){
	node *p_pre,*p_next,*p_new;
	p_next = head;
	//分配一个node节点空间,初始化内部值
	p_new = (node *)malloc(sizeof(node));
	p_new->data = num;
	//搜索插入节点的位置,按照从小到大的插入方法
	while((p_new->data > p_next->data) && (p_next->next != NULL)){
		p_pre = p_next;
		p_next = p_next->next;
	}
	if(p_new->data <= p_next->data){
		//开头处理
		if(p_next == head){
			head = p_new;
			p_new->next = p_next;
		}else if(p_next->next == NULL){//结尾处理
			p_next->next = p_new;
			p_new->next = NULL;
		}else{//中间部分处理
			p_pre->next = p_new;
			p_new->next = p_next;
		}
	}
	return head;
}

 

题目三:实现单链表的排序。

//排序链表,从小到大排序,实质上是内容的排序
node* sort_node(node *head){
	node *p;
	if(head == NULL|| head->next==NULL)
		return head;
	int temp;
	int n  =length(head);//该函数在题目一种已经写过
	//采用的排序方法为冒泡法
	for(int i = 1;i<n;i++){
		p = head;
		for(int j=0;j<n-i;j++){
			if(p->data > p->next->data){
				temp = p->data;//进行值得交换
				p->data = p->next->data;
				p->next->data = temp;
			}
			p = p->next;//移动到下一个节点
		}
	}
	return head;
}


题目四:编程实现单链表的逆置。

//逆序排列只需要将指针位置调换即可;
node* reverse_node(node *head){
	node *p1,*p2,*temp1,*temp2;
	p1 = head;
	p2 = p1->next;
	if(head ==NULL || head->next ==NULL){
		return head;
	}
	while(p2->next!=NULL){
		//保护现场
		temp1 = p2;
		temp2 = p2->next;
		//对单向链头部情况进行处理
		if(p1==head){
			p1->next= NULL;
			p2->next = p1;
		}else{
			p2->next = p1;
		}
		//现场恢复进行移位
		p1 = temp1;
		p2 = temp2;
	}
	//将原链表最后一个元素的next指针指向反向排序好的位置。
	p2->next = p1;
	//将尾部改换成头部
	head = p2;
	return head;
}



CF

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值