链表是一种基本的数据结构,每个数据项中都包含我们所需的到达下一个数据项的信息。链表比数组的优势在于,它可以提供高效的重排数据项的能力。
链表是一组数据项的集合,其中每个数据项都是一个节点的一部分,每个节点都包含指向下一个节点的连接。
链表中的末尾节点约定:
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