一.单向链表的操作
1.创建单链表 2.创建结点 3.头插 4.头删 5.输出 6.尾插 7.尾删 8.按位置插入 9.按位置删除
#ifndef __LINK_LIST_H__
#define __LINK_LIST_H___
#include <stdlib.h>
#include <stdio.h>
typedef struct node
{
int data; //数据域
struct node *next; //指针域,指向下一个结点
}node,*node_p;
//创建单链表,实际上是创建头结点
node_p create_link_list();
//创建结点,创建数据结点
node_p create_node(int data);
//头插
void insert_head(node_p H,int data);
//单链表的判空
int empty_link(node_p H);
//输出
void show_link(node_p H);
//头删
void del_head(node_p H);
//尾插
void insert_tail(node_p H,int data);
//尾删
void dele_tail(node_p H);
//按位置插入
void insert_pos(node_p H,int data,int pos);
//按位置删除
void delete_pos(node_p H,int pos);
#endif
#include "link_list.h"
//创建单链表,实际上是创建头结点
node_p create_link_list()
{
node_p H=(node_p)malloc(sizeof(node));
if(H==NULL)
{
printf("空间申请失败\n");
return NULL;
}
H->data=0; //刚创建链表时,链表没有结点
H->next=NULL; //链表中没有结点,头结点指向空
return H;
}
//创建结点,创建数据结点
node_p create_node(int data)
{
node_p new=(node_p)malloc(sizeof(node));
if(new==NULL)
{
printf("空间申请失败\n");
return NULL;
}
new->data=data;
return new;
}
//头插
void insert_head(node_p H,int data)
{
//入参合理性检查
if(H==NULL)
{
printf("入参为空\n");
return;
}
//给数据申请结点
node_p new=create_node(data); //返回堆区申请的空间的首地址
new->next=H->next; //新结点的指针域指向原来头结点指向的结点
H->next=new; //头结点指向新节点
H->data++; //将头结点存储的链表长度自增
}
//单链表的判空
int empty_link(node_p H)
{
if(H==NULL)
{
printf("入参为空\n");
return -1;
}
return H->next==NULL?1:0;;
}
//输出
void show_link(node_p H)
{
//入参合理性检查
if(H==NULL)
{
printf("入参为空\n");
return;
}
if(empty_link(H))
{
printf("入参为空\n");
return;
}
node_p p=H->next; //从第一个结点(头结点的下一个节点)开始输出
//最有一个结点需要进入循环并输出
while(p!=NULL)
{
printf("%d->",p->data);
p=p->next; //让指针p指向下一个结点
}
printf("NULL\n");
}
//头删
void del_head(node_p H)
{
if(H==NULL)
{
printf("入参为空\n");
return;
}
if(empty_link(H))
{
printf("表为空\n");
return;
}
node_p del=H->next; //保存要删除的结点
H->next=H->next->next; //让头结点指向第二结点
free(del); //释放要删除的结点
H->data--;
}
//尾插
void insert_tail(node_p H,int data)
{
if(H==NULL)
{
printf("入参为空\n");
return;
}
//找到尾结点
node_p p=H;
//判断尾结点的条件:指针域为空
while(p->next!=NULL)
{
p=p->next; //p指向下一个节点
}
//申请新结点
node_p new=create_node(data);
//让新结点的指针域,保留原来尾结点的指针域
new->next=p->next;
//原来的尾结点指向新结点
p->next=new;
H->data++;
}
//尾删
void dele_tail(node_p H)
{
if(H==NULL)
{
printf("入参为空\n");
return;
}
if(empty_link(H))
{
printf("表为空\n");
return;
}
//找到倒数第二个结点
node_p p=H;
while(p->next->next!=NULL)
{
p=p->next;
}
//保留要删除的结点
node_p del=p->next;
//将倒数第二个结点的指针域,指空
p->next=p->next->next;
free(del);
}
//按位置插入
void insert_pos(node_p H,int data,int pos)
{
if(H==NULL)
{
printf("入参为空\n");
return;
}
//判断位置不合理的情况
//保证数据间逻辑上的一对一关系
//如果有5个元素,往第六个位置插入,相当于尾插
if(pos<=0 || pos>H->data+1)
{
printf("位置不合理\n");
return;
}
//找到pos-1位置的终点
int i; //记录位置
node_p p=H; //让指针从结点出发
//找到pos-1位置的终点
for(i=0;i<pos-1;i++)
{
p=p->next;
}
//申请新结点
node_p new=create_node(data);
//让新结点的指针指向原来pos位置的结点
new->next=p->next;
//让pos-1位置的结点指向新结点
p->next=new;
H->data++;
}
//按位置删除
void delete_pos(node_p H,int pos)
{
if(H==NULL)
{
printf("入参为空\n");
return;
}
if(empty_link(H))
{
printf("表为空\n");
return;
}
if(pos<=0 || pos>H->data)
{
printf("输入不合理\n");
return;
}
node_p temp=H;
for(int i=0;i<pos-1;i++)
{
temp=temp->next;
}
node_p temp2=temp->next;
temp->next=temp->next->next;
free(temp2);
H->data--;
}
#include "link_list.h"
int main()
{
node_p H=create_link_list();
insert_head(H,90);
insert_head(H,71);
insert_head(H,59);
insert_head(H,10);
//show_link(H);
insert_tail(H,23);
insert_tail(H,74);
//dele_tail(H);
insert_pos(H,456,3);
show_link(H);
delete_pos(H,5);
show_link(H);
return 0;
}
二.求以下结构体的大小
#pragma pack(2) //指定两字节对齐
typedef struct
{
char x;
struct A
{
short a;
int *b;
char c;
}p;
long b;
}T;
#pragma pack()
1.指定对齐2字节
2.char x -->1字节
3.struct A
{
short a; --> 2字节
int *b; --> 8字节
char c; --> 1字节
}
4.long b; --> 8字节
指定2字节对齐 最后结果为: 1+(1)+11+(1)+8=22 ()括号里面为根据指定对齐补的内存