结构体与指针
#include "stdafx.h"
#define IS_FULL(p) (!p)
/*
struct node
{
int Date;
struct node* Link; //自引用结构,即结构中有一个或多个成员是指向它自身的指针
};
*/
//typedef struct node* Nodeptr; 定义一个新的类型
typedef struct node
{
int date;
struct node* Link;
}Node;
int _tmain(int argc, _TCHAR* argv[])
{
Node* p = (Node*)malloc(sizeof(Node)); //动态创建变量,存储在堆(heap)中
if (IS_FULL(p))
{
fprintf(stderr, "The memory is full\n");
exit(1);
}
free(p);//释放内存
return 0;
}
单链表的结点结构
include "stdafx.h"
#define IS_FULL(ptr) (!(ptr))
typedef struct node //单链表的结点结构
{
int Element; //元素域
struct node* Link; //指针域
}Node;
typedef int T;
typedef Node* List;//单链表类型
T* InputElement() //输入元素
{
static T a;
scanf("%d", &a);
return &a;
}
void PrintElement(T x) //输出元素
{
printf("%d", x);
}
创建结点的三个方法
Node* NewNode()
{
Node* p = (Node*)malloc(sizeof(Node));
if (IS_FULL(p))
{
fprintf(stderr, "The memory is full");
exit(1);
}
p->Link = NULL;
return p;
}
Node* NewNode1()
{
Node* p = (Node*)malloc(sizeof(Node));
if (IS_FULL(p))
{
fprintf(stderr, "The memory is full");
exit(1);
}
p->Element = *InputElement();
p->Link = NULL;
return p;
}
Node* NewNode2(T x)
{
Node* p = (Node*)malloc(sizeof(Node));
if (IS_FULL(p))
{
fprintf(stderr, "The memory is full");
exit(1);
}
p->Element = x;
p->Link = NULL;
return p;
}
插入结点
Node* InsertNode(Node* p)
{
Node* newnode = NewNode2(4);
if (IS_FULL(newnode))
{
fprintf(stderr, "The memory is full");
return false;
}
newnode->Link = p->Link;
p->Link = newnode;
return newnode;
}
建立单链表
#include<ctype.h>
typedef Node* List;
List BulidList()
{
Node* p,*r=NULL,*first = NULL;char c;
printf("Another element?y/n");
while((c=getchar()) == '\n');//接受掉第二个回车
while(tolower(c) != 'n')
{
p = NewNode1();
if(first != NULL)//如果不是空表,则插在表后
r->Link = p;
else
first = p;//如果是空表则插在第一个
r = p;//r指向最后一个结点
printf("Another element? y/n");
while((c=getchar()) == '\n');//接受掉第二个回车
}
return first;
}
输出链表
void PrintList(List first)
{
printf("\n the list contains:\n");
for(;first;first=first->Link) //由首结点依次后移
PrintElement(first->Element);
printf"\n\n");
}
清空链表
void Clear(List* first) //传递的是引用,否则按值复制,释放后为NULL,清除后,lst仍然指向原地址,而原地址里已经释放作它用。
{
Node* p= *first;//首结点指针赋给p
while(*first)
{
p =(*first)->Link;//结点不为空的话赋给p
free(*first);//删除首结点
*first = p;//结点后移
}
}
驱动程序(driver),即软件模块化设计中的为单独调试和测试的一个函数而设计的辅助程序。
void main()
{
List list;
lst = BulidList();
PrintElement(lst);
Clear(&lst);
PrintList(lst);
}
带表头结点的单链表
在单链表前增加一个结点,成为表头结点。表头结点不存放单链表的元素,它或为空,或者用于存放实现算法所需的辅助数据
双向链表的结构类型
typedef struct dnode
{
T Element;//元素域
struct dnode* RLink,*LLink;//前趋结点指针,后驱结点指针
}DNode;
注:指针指向结点的任何一个地方都是等价的,都是指向它所指示的结点的起始地址。
q结点插入在p结点前面
插入操作的核心步骤:
q->LLink = p->LLink;
q->RLink = p;
p->LLink->RLink = q;
p->LLink = q;
删除操作的核心步骤:
p-LLink->RLink = p->RLink;
p->RLink->LLink = p->LLink;
free(p);