例子:
struct node
{
int data;
node * next;
};
next:指向下一个node类型的结构,连接node 的纽带
存放学生信息的链表节点
struct student {
int num;
char name[20];
char sex;
float score;
student * next;
};
动态申请内存的方法
student *p=(student*) malloc(sizeof(student));
student * p = new student;
建立单向链表
- 声明一个链首指针变量head,并赋初值NULL(包含0个节点的链表)
- 动态分配一个新节点,将该节点链入链尾
- 重复上一步
例子1:建立链表,读入n个整数,每个整数作为一个新结点插入到链尾
#include <iostream>
using namespace std;
struct node
{
int data;
node * next;
};
node * createList(int n);
int main()
{
int n;
node * listHead = NULL;
cout << "Please enter the number of nodes:";
cin >> n;
if (n > 0)
listHead = createList(n);
return 0;
}
node *createList(int n)
{
node *temp, *tail = NULL, *head = NULL ;
int num;
cin >> num;
head = new node ; // 为新节点动态分配内存
if (head == NULL)
{
cout << "No memory available!";
return NULL;
}
else
{
head->data = num;
head->next = NULL;
tail = head;
}
for ( int i = 0; i < n - 1; i ++)
{
cin >> num;
temp = new node ; // 为新节点动态分配内存
if (temp == NULL)
{
cout << "No memory available!";
return head;
}
else
{
temp->data = num;
temp->next = NULL;
tail->next = temp;
tail = temp;
}
}
return head ;
}
遍历链表
依次访问链表中的每个节点的信息
head->data = 15;
head->next->data = 15;
一般遍历方法
node * curNode = head;
while (curNode )
curNode = curNode->next;
例子2:编写一个函数,输出例1链表中各节点的data成员的值
void outputList(node * head)
{
cout << "List: ";
node *curNode = head;
while ( curNode )
{
cout << curNode->data;
if (curNode ->next)
cout << " -> ";
curNode = curNode ->next;
}
cout << endl;
return;
}
例子3:编写一个函数,在例1的链表中查找包含指定整数的节点
node * findData(int n, node * head)
{
node *curNode = head;
while ( curNode )
{
if ( curNode->data == n)
{
cout<<"Find "<<n<<" in the list."<<endl;
return curNode;
}
curNode = curNode->next;
}
cout<<"Can't find "<<n<<" in the list."<<endl;
return NULL;
}
在链表中节点a之后插入节点c
(1) 指针cptr指向节点c,aptr指向节点a;
(2) 把a后继节点的地址赋给节点c的后继指针
cptr->next=aptr->next;
(3) 把c的地址赋给节点a的后继指针
aptr->next=cptr;
例子4:编写一个函数,将输入的整数从小到大插入链表
node * insertData(int n, node * head)
{
node *curNode = head;// 指向插入点的后节点
node *preNode = NULL;// 指向插入点的前节点
node *newNode = NULL;// 指向新建节点
while ((curNode!=NULL)&&(curNode->data<n))
{
preNode = curNode; // 后节点变为前节点
curNode = curNode->next;
}
newNode = new node ;
if (newNode == NULL)
{
cout << "No memory available!";
return head;
}
newNode->data = n;
if (preNode == NULL) //插入到链表头
{
newNode->next = curNode;
return newNode;
}
else
{
preNode->next = newNode;
newNode->next = curNode;
return head;
}
}
从链表中删除一个节点c
(1)在链表中查找要删除的节点c,用指针cptr指向节点c;
(2)如果c有前驱节点(设为d,用指针dptr指向d),则将d的后继指针指向c的后继节点:dptr->next=cptr->next
(3)释放c占用的空间
例子5:编写一个函数,删除链表中包含指定整数的节点
node * deleteData(int n, node * head)
{
node *curNode = head;// 指向当前节点
node *preNode = NULL;// 指向当前节点的前驱节点
while (curNode && curNode->data != n)
{
preNode = curNode; // 当前节点变为前驱节点
curNode = curNode->next;
}
if (curNode == NULL)
{
cout<<"Can't find "<<n<<" in the list"<<endl;
return head;
}
if (preNode == NULL) //删除链首节点
head = head->next;
else
preNode->next = curNode->next;
delete curNode;
return head; // 返回链首指针
}