凡老师:
目录
链表创建的两种方式
指定值位于第几个结点
插入结点
反转链表
链表排序
删除单个结点
无图警告:就图一乐!
单链表是是顺序表的另一种表现形式:通过链式存储,可以非常方便的插入与删除表中的某一元素,因为地址不是连续的,链表的维系是靠单结点的指针来进行链接,所以插入与删除仅需修改一个指针即可。
说明:代码里的第一个head为头结点,既虚拟结点,此处我存放-1作标识。
创建链表的两种方式:
头插法:
LinkPtr AppendNode_head(LinkPtr head, int data) {
LinkPtr p = NULL, pr = head;
p = (Link*)malloc(sizeof(Link));
p->data = data;
if (head == NULL) {
head = p;
p->next = NULL;
}
else {
p->next = pr;
head = p;
}
return head;
}
尾插法:
LinkPtr AppendNode_tail(LinkPtr head,int data){//tail
LinkPtr p = NULL, pr = head;
p = (Link*)malloc(sizeof(Link));
p->next = NULL;
if (head == NULL) {
head = p;
}
else {
while (pr->next) {
pr = pr->next;
}
pr->next = p;
}
p->data = data;
return head;
}
结点寻址:
int LocateNode(LinkPtr head,int target) {
LinkPtr p = head->next;
int cnt = 0;
while (p) {
if (p->data == target) return cnt;
p = p->next;
cnt++;
}
return -1;
}
插入结点:
void Link_Insert(LinkPtr head,int pos,int data) {
LinkPtr p = head,q;
LinkPtr node = (Link*)malloc(sizeof(Link));
node->data = data;
for (int i = 0; i < pos; i++) {
p = p->next;
if (p->next == NULL) {
break;
}
}
q = p->next;
p->next = node;
node->next = q;
}
反转链表:
LinkPtr Link_Reverse(LinkPtr head) {
LinkPtr newHead = NULL, p;
while (head) {
p = head;
head = head->next;
p->next = newHead;
newHead = p;
}
return newHead;
}
链表排序:使用了最简单的排序方法--冒泡排序;而且交换就仅仅只交换数据域即可,指针不会发生变化。
void Link_Sort(LinkPtr head){
LinkPtr p, q;
int t;
p = head->next;
while (p != NULL){
q = p->next;
while (q != NULL){
if (p->data > q->data){
t = p->data;
p->data = q->data;
q->data = t;
}
q = q->next;
}
p = p->next;
}
}
删除单个结点:
void Delete_A_Node(LinkPtr head,int pos) {
LinkPtr p = head,q;
for (int i = 0; i < pos; i++) {
p = p->next;
if (p->next == NULL) {
return;
}
}
q = p->next;
p->next = q->next;
free(q);
}
完整代码与运行截图:
还有
#include<stdio.h>
#include<malloc.h>
typedef struct link {
int data;
struct link* next;
}Link,*LinkPtr;
LinkPtr AppendNode_tail(LinkPtr head,int data){//tail
LinkPtr p = NULL, pr = head;
p = (Link*)malloc(sizeof(Link));
p->next = NULL;
if (head == NULL) {
head = p;
}
else {
while (pr->next) {
pr = pr->next;
}
pr->next = p;
}
p->data = data;
return head;
}
LinkPtr AppendNode_head(LinkPtr head, int data) {
LinkPtr p = NULL, pr = head;
p = (Link*)malloc(sizeof(Link));
p->data = data;
if (head == NULL) {
head = p;
p->next = NULL;
}
else {
p->next = pr;
head = p;
}
return head;
}
void outputNode(LinkPtr head) {
LinkPtr p=head;
while (p) {
printf("%d ", p->data);
p = p->next;
}
}
void ClearLink(LinkPtr head) {
LinkPtr p = head, pr = NULL;
while (p) {
pr = p;
p = p->next;
free(pr);
}
}
int LocateNode(LinkPtr head,int target) {
LinkPtr p = head->next;
int cnt = 0;
while (p) {
if (p->data == target) return cnt;
p = p->next;
cnt++;
}
return -1;
}
LinkPtr Link_Reverse(LinkPtr head) {
LinkPtr newHead = NULL, p;
while (head) {
p = head;
head = head->next;
p->next = newHead;
newHead = p;
}
return newHead;
}
void Link_Insert(LinkPtr head,int pos,int data) {
LinkPtr p = head,q;
LinkPtr node = (Link*)malloc(sizeof(Link));
node->data = data;
for (int i = 0; i < pos; i++) {
p = p->next;
if (p->next == NULL) {
break;
}
}
q = p->next;
p->next = node;
node->next = q;
}
void Delete_A_Node(LinkPtr head,int pos) {
LinkPtr p = head,q;
for (int i = 0; i < pos; i++) {
p = p->next;
if (p->next == NULL) {
return;
}
}
q = p->next;
p->next = q->next;
free(q);
}
void Link_Sort(LinkPtr head){
LinkPtr p, q;
int t;
p = head->next;
while (p != NULL){
q = p->next;
while (q != NULL){
if (p->data > q->data){
t = p->data;
p->data = q->data;
q->data = t;
}
q = q->next;
}
p = p->next;
}
}
int NodeTest() {
int a[5] = { 2,5,7,4,1 };
LinkPtr head = NULL;
head = AppendNode_tail(head, -1);//虚拟头结点
for (int i = 0; i < 5; i++) {
head = AppendNode_tail(head, a[i]);
}
printf("the target 1 position :%d \n", LocateNode(head, 1));
outputNode(head);
putchar('\n');
printf("将链表排序:\n");
Link_Sort(head);
outputNode(head);
putchar('\n');
printf("插入结点data:99于第二个位置\n");
Link_Insert(head, 2, 99);
outputNode(head);
putchar('\n');
printf("删除第二个位置的结点\n");
Delete_A_Node(head, 2);
outputNode(head);
putchar('\n');
ClearLink(head);
return 1;
}
int NodeTest1() {
int a[5] = { 2,5,7,4,1 };
LinkPtr head = NULL;
head = AppendNode_head(head, -1);//虚拟头结点
for (int i = 0; i < 5; i++) {
head = AppendNode_head(head, a[i]);
}
outputNode(head);
printf("将链表反转:\n");
LinkPtr newhead = Link_Reverse(head);
outputNode(newhead);
ClearLink(head);
return 1;
}
int main() {
NodeTest();
NodeTest1();
return 0;
}